分布式RPC架構Apache Dubbo
- 軟體架構的演進過程
-
- 1· 單體架構
- 2· 垂直架構
- 3· SOA架構
- 4· 微服務架構
- Dubbo簡介
- 服務注冊中心Zookeeper
-
- Zookeeper樹型目錄服務:
- Dubbo協定
- Dubbo的負載均衡
- 給Dubbo添加事務
-
- @Transactional
- 解決方法
軟體架構的演進過程
軟體架構的發展經曆了由單體架構、垂直架構、SOA架構到微服務架構的演進過程
1· 單體架構
全部功能集中在一個項目内(All in one)
架構優點:
架構簡單,前期開發成本低、開發周期短,适合小型項目。
架構缺點:
全部功能內建在一個工程中,對于大型項目不易開發、擴充和維護。
技術棧受限,隻能使用一種語言開發。
系統性能擴充隻能通過擴充叢集節點,成本高。
最初學習的項目就是為單體架構
2· 垂直架構
按照業務進行切割,形成小的單體項目。
架構優點:
技術棧可擴充(不同的系統可以用不同的程式設計語言編寫)。
架構缺點:
功能集中在一個項目中,不利于開發、擴充、維護。
系統擴張隻能通過叢集的方式。
項目之間功能備援、資料備援、耦合性強。
3· SOA架構
SOA全稱為Service-Oriented Architecture,即面向服務的架構。它可以根據需求通過網絡對松散耦合的粗粒度應用元件(服務)進行分布式部署、組合和使用。一個服務通常以獨立的形式存在于作業系統程序中。
站在功能的角度,把業務邏輯抽象成可複用的服務,通過服務的編排實作業務的快速再生,目的:把原先固有的業務功能轉變為通用的業務服務,實作業務邏輯的快速複用。
将重複功能或子產品抽取成元件的形式,對外提供服務,在項目與服務之間使用ESB(企業服務總線)的形式作為通信的橋梁。
架構優點:
重複功能或子產品抽取為服務,提高開發效率。
可重用性高。
可維護性高。
架構缺點:
各系統之間業務不同,很難确認功能或子產品是重複的。
抽取服務的粒度大。
系統和服務之間耦合度高。
目前大部分小型公司采用SOA架構
4· 微服務架構
将系統服務層完全獨立出來,抽取為一個一個的微服務。
抽取的粒度更細,遵循單一原則。
采用輕量級架構協定傳輸。
架構優點:
服務拆分粒度更細,有利于提高開發效率。
可以針對不同服務制定對應的優化方案。
适用于網際網路時代,産品疊代周期更短。
架構缺點:
粒度太細導緻服務太多,維護成本高。
分布式系統開發的技術成本高,對團隊的挑戰大。
目前市場上主流架構為微服務架構
Dubbo簡介
Apache Dubbo是一款高性能的Java RPC架構。其前身是阿裡巴巴公司開源的、輕量級的開源Java RPC架構,可以和Spring架構無縫內建,2018年阿裡巴巴把這個架構捐獻給了apache基金會。
RPC全稱為remote procedure call,即遠端過程調用。RPC是一個泛化的概念,嚴格來說一切遠端過程調用手段都屬于RPC範疇。
Dubbo提供了三大核心能力:面向接口的遠端方法調用,智能容錯和負載均衡,以及服務自動注冊和發現。
服務注冊中心Zookeeper
Zookeeper 是 Apache Hadoop 的子項目,是一個樹型的目錄服務,支援變更推送,适合作為 Dubbo服務的注冊中心,工業強度較高,可用于生産環境,并推薦使用 。
Zookeeper樹型目錄服務:
服務提供者(Provider)啟動時: 向 /dubbo/com.foo.BarService/providers 目錄下寫入自己的URL 位址;
服務消費者(Consumer)啟動時: 訂閱 /dubbo/com.foo.BarService/providers 目錄下的提供者URL 位址。并向 /dubbo/com.foo.BarService/consumers 目錄下寫入自己的 URL 位址;
監控中心(Monitor)啟動時: 訂閱 /dubbo/com.foo.BarService 目錄下的所有提供者和消費者URL 位址;
Dubbo協定
Dubbo支援的協定有:dubbo、rmi、hessian、http、webservice、rest、redis等。
推薦使用的是dubbo協定,預設的端口号為20880
dubbo 協定采用單一長連接配接和 NIO 異步通訊,适合于小資料量大并發的服務調用,以及服務消費者機器數遠大于服務提供者機器數的情況。不适合傳送大資料量的服務,比如傳檔案,傳視訊等,除非請求量很低。
dubbo也可以在同一個工程中配置多個協定,不同服務可以使用不同的協定。
Dubbo的負載均衡
負載均衡(Load Balance):其實就是将請求分攤到多個操作單元上進行執行,進而共同完成工作任務。
在叢集負載均衡時,Dubbo 提供了多種均衡政策(包括随機、輪詢、最少活躍調用數、一緻性Hash),預設為random随機調用。
配置負載均衡政策,既可以在服務提供者一方配置,也可以在服務消費者一方配置:
public class HelloController {
//在服務消費者一方配置負載均衡政策
@Reference(check = false,loadbalance = "random")
private HelloService helloService;
//在服務提供者一方配置負載均衡
@Service(loadbalance = "random")
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello " + name;
}
}
給Dubbo添加事務
@Transactional
Dubboo通過提供的标簽配置進行包掃描,掃描到@Service注解的類後被釋出為服務。
但是在服務提供者類上加入@Transactional事務控制注解後,服務就釋出不成功了。原因是@Transactional注解的底層原理是為服務提供者類建立代理對象,預設情況下Spring是基于JDK動态代理方式建立代理對象,代理對象的完整類名為com.sun.proxy.$Proxy42(最後兩位數字不是固定的)。導緻
Dubbo在釋出服務前進行包比對時無法完成比對,進而沒有進行服務的釋出。
根據源碼可看出 beanClassName包的位址不能與pkg,無法傳回ture。
解決方法
在l類上加入事務注解後,Spring會為此類基于JDK動态代理技術建立代理對象,建立的代理對象完整類名為com.sun.proxy.$Proxy35,導緻Dubbo在進行包比對時沒有成功。
(1)修改applicationContext-service.xml配置檔案,開啟事務控制注解支援時指定proxy-target-class屬性,值為true。其作用是使用cglib代理方式為Service類建立代理對象
<!--開啟事務控制的注解支援-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-targetclass="true"/>
(2)修改HelloServiceImpl類,在Service注解中加入interfaceClass屬性,值為HelloService.class,作用是指定服務的接口類型
@Service(interfaceClass = HelloService.class)
@Transactional
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello " + name;
}
}