1.概念html
1.1 SOAjava
面向服務架構,SOA是一種思想node
備註:分佈式系統的發展與演變 orm -mvc-rpc-soa程序員
1.2 RPC算法
RPC是指遠程過程調用,是一種進程間通訊方式,他是一種技術的思想,而不是規範。它容許程序調用另外一個地址空間(一般是共享網絡的另外一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。RPC能夠理解爲SOA的一種實現spring
RPC兩個核心模塊:通信,序列化。數據庫
服務消費方(client)調用以本地調用方式調用服務;apache
1> client stub接收到調用後負責將方法、參數等組裝成可以進行網絡傳輸的消息體;設計模式
2> client stub找到服務地址,並將消息發送到服務端;緩存
3> server stub收到消息後進行解碼;
4> server stub根據解碼結果調用本地的服務;
5> 本地服務執行並將結果返回給server stub;
6> server stub將返回結果打包成消息併發送至消費方;
7> client stub接收到消息,並進行解碼;
8> 服務消費方獲得最終結果。
2 Dubbo(12年中止維護,17後又在維護,依賴於spring環境,dubbo的2.6以上版本是dubbox與之前的dubbo的一個整合並貢獻給Apache)
官方文檔: http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
一個分佈式、高性能、透明化的RPC服務框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。
灰度服務(慢慢的轉移到新的服務器的過程)
2.1 Dubbo架構圖
Provider :提供者,服務發佈方.
Consumer:消費者, 調用服務方
Container:Dubbo容器.依賴於Spring容器.
Registry: 註冊中心.當Container啓動時把全部能夠提供的服務列表上Registry中進行註冊.做用:告訴Consumer提供了什麼服務和服務方在哪裏.
Monitor:監聽器
虛線都是異步訪問,實線都是同步訪問
藍色虛線:在啓動時完成的功能
紅色虛線(實線)都是程序運行過程當中執行的功能
全部的角色都是能夠在單獨的服務器上.因此必須遵照特定的協議.
運行原理:
啓動容器,至關於在啓動Dubbo的Provider
啓動後會去註冊中心進行註冊.註冊全部能夠提供的服務列表
在Consumer啓動後會去Registry中獲取服務列表和Provider的地址.進行訂閱.
當Provider有修改後,註冊中心會把消息推送給Consumme, 使用了觀察者設計模式(又叫發佈/訂閱設計模式)
根據獲取到的Provider地址,真實調用Provider中功能.在Consumer方使用了代理設計模式.建立一個Provider方類的一個代理對象.經過代理對象獲取Provider中真實功能,起到保護Provider真實功能的做用.
Consumer和Provider每隔1分鐘向Monitor發送統計信息,統計信息包含,訪問次數,頻率等.
備註:invoke 最耗時,register是自動運行的,
2.2 註冊中心
Zookeper:優勢:支持網絡集羣,缺點:穩定性受限於Zookeeper
Redis:優勢:性能高,缺點:對服務器環境要求較高
Multicast: 優勢:面中心化,不須要額外安裝軟件,缺點:建議同機房(局域網)內使用
Simple:適用於測試環境.不支持集羣.
Dubbo支持的協議
2.3 Dubbo協議
Dubbo官方推薦的協議.本質:使用NIO和線程池進行處理.缺點:大文件傳輸時可能出現文件傳輸失敗問題.
RMI協議
JDK提供的協議,遠程方法調用協議. 缺點:偶爾鏈接失敗. 優勢:JDK原生,不須要進行額外配置(導入jar)
Hession協議
優勢:基於http協議,http請求支持. 缺點:須要額外導入jar,並在短鏈接時性能低
2.4 zookeeper安裝
見zookeeper
2.5 dubbo-admin的配置與使用
2.6.0以後是springboot寫的,配置按需修改配置,只須要修改registry.address而後啓動便可。
javassist異常
<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> <exclusions> <exclusion> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.21.0-GA</version> </dependency>
2.6 monitor 的配置與使用
配置monitor 只須要修改registry.address啓動便可。
在 Provide與Consumer的application中添加以下配置
<!--方式1:註冊,自動檢查--> <dubbo:monitor protocol="registry"/> <!--方式2:admin的地址--> <dubbo:monitor address="127.0.0.1:7070" />
2.7 簡單實例搭建配置版
依賴provide
<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.dubbo.provide</groupId> <artifactId>dubbo-provide</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>cn.dubbo.base</groupId> <artifactId>dubbo-base</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.4</version> <exclusions> <exclusion> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.21.0-GA</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> </dependencies> </project>
application配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--應用名稱--> <dubbo:application name="dubboService"/> <!--註冊中心 協議 地址--> <dubbo:registry address="192.168.1.128:2181" protocol="zookeeper"/> <!--協議 名稱與端口--> <dubbo:protocol name="dubbo" port="20880" /> <!--暴露接口 ref指向的實體類--> <dubbo:service interface="cn.dubbo.service.ProvideService" ref="demoControllerImpl"/> <bean id="demoControllerImpl" class="cn.dubbo.service.ProvideServiceImpl"/> </beans>
其餘
public interface ProvideService { public String test(); }
public class ProvideServiceImpl implements ProvideService { public String test() { return "hello"; } }
public class ProvideTest { public static void main(String[] args) { new ClassPathXmlApplicationContext("classpath:application.xml"); Main.main(args); } }
依賴consumer
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.dubboc.test</groupId> <artifactId>DubbocTest</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>cn.dubbo.provide</groupId> <artifactId>dubbo-provide</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
application配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="dubboService"/> <dubbo:registry address="192.168.1.128:2181" protocol="zookeeper"/> <dubbo:annotation package="cn.dubbo.service"/>//也可使用refrence,可是須要使用@Autowired以及@service
<!--註冊監控中心,自動檢查-->
<dubbo:monitor protocol="registry"/> <bean id="consumerServiceImpl" class="cn.dubbo.service.ConsumerServiceImpl"/> </beans>
其餘:
public interface ConsumerService { public void test(); } public class ConsumerServiceImpl implements ConsumerService { @Reference ProvideService provideService; public void test() { String test = provideService.test(); System.out.println(test); } } public class ConsumerTest { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:application.xml"); ConsumerServiceImpl consumerServiceImpl = ctx.getBean("consumerServiceImpl", ConsumerServiceImpl.class); consumerServiceImpl.test(); } }
2.8 在springoot中使用
在springboot中添加以下依賴
dubbo.application.name=provide dubbo.registry.protocol=zookeeper dubbo.registry.address=192.168.1.128:2181 dubbo.protocol.name=dubbo dubbo.protocol.port=20881
暴露接口,固然還須要注入容器,夏苗苗兩個註解沒有注入容器
@Service//import com.alibaba.dubbo.config.annotation.Service; @EnableDubbo public class ProvideServiceImpl implements ProvideService {
2.9 配置文件讀取優先級
2.10 啓動時檢查
<!--單個配置-->
@Reference(check = false) ProvideService provideService;
<!--統一配置-->
<dubbo:consumer check="false"/>
假如沒有check = false,那麼啓動時必須調用提供者的方法否者報錯,設置後只有真正在調用的時候纔會去檢查
2.11 超時設置
因爲網絡或服務端不可靠,會致使調用出現一種不肯定的中間狀態(超時)。爲了不超時致使客戶端資源(線程)掛起耗盡,必須設置超時時間,默認也設置超時時間
Dubbo消費端
<!--單個配置-->
@Reference(check = false,timeout = 1000)
<!--統一配置-->
<dubbo:consumer timeout="5000" />
Dubbo服務端
<!--單個配置-->
<dubbo:provider interface="com.foo.BarService" timeout="2000"> <dubbo:method name="sayHello" timeout="3000" /> </dubbo:provider> <!--統一配置--> <dubbo:provider timeout="5000" />
配置原則
dubbo推薦在Provider上儘可能多配置Consumer端屬性:
方法級配置別優先於接口級別,即小Scope優先
Consumer端配置 優先於 Provider配置 優於 全局配置
2.12 重試次數
失敗自動切換,當出現失敗,重試其它服務器,但重試會帶來更長延遲。可經過 retries="2" 來設置重試次數(不含第一次)。
<!--重試次數配置方式1--> <dubbo:service retries="2" /> <!--重試次數配置方式2--> @Reference(check = false,timeout = 1000,retries = 2)
ProvideService provideService;
2.13 版本號
當一個接口實現,出現不兼容升級時,能夠用版本號過渡,版本號不一樣的服務相互間不引用。能夠按照如下的步驟進行版本遷移:
在低壓力時間段,先升級一半提供者爲新版本再將全部消費者升級爲新版本而後將剩下的一半提供者升級爲新版本
老版本服務提供者配置: <dubbo:service interface="com.foo.BarService" version="1.0.0" /> 新版本服務提供者配置: <dubbo:service interface="com.foo.BarService" version="2.0.0" /> <dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" /> 新版本服務消費者配置: <dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" /> 若是不須要區分版本,能夠按照如下的方式配置: <dubbo:reference id="barService" interface="com.foo.BarService" version="*" />
2.14 本地存根
調用接口以前,先調用stub
<dubbo:service interface="com.foo.BarService" stub="true" /> 或 <dubbo:service interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
2.15 zookeeper宕機與dubbo直連
zookeeper宕機
監控中心宕掉不影響使用,只是丟失部分採樣數據
數據庫宕掉後,註冊中心仍能經過緩存提供服務列表查詢,但不能註冊新服務
註冊中心對等集羣,任意一臺宕掉後,將自動切換到另外一臺
註冊中心所有宕掉後,服務提供者和服務消費者仍能經過本地緩存通信
服務提供者無狀態,任意一臺宕掉後,不影響使用
服務提供者所有宕掉後,服務消費者應用將沒法使用,並沒有限次重連等待服務提供者恢復
dubbo直連
@Reference(url = "127.0.0.1:20880")
2.16 負載均衡策略
Random LoadBalance
隨機,按權重設置隨機機率。
在一個截面上碰撞的機率高,但調用量越大分佈越均勻,並且按機率使用權重後也比較均勻,有利於動態調整提供者權重。
RoundRobin LoadBalance
輪循,按公約後的權重設置輪循比率。
存在慢的提供者累積請求的問題,好比:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,長此以往,全部請求都卡在調到第二臺上。
LeastActive LoadBalance
最少活躍調用數,相同活躍數的隨機,活躍數指調用先後計數差。
使慢的提供者收到更少請求,由於越慢的提供者的調用先後計數差會越大。
ConsistentHash LoadBalance
一致性 Hash,相同參數的請求老是發到同一提供者。
當某一臺提供者掛時,本來發往該提供者的請求,基於虛擬節點,平攤到其它提供者,不會引發劇烈變更。算法參見:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只對第一個參數 Hash,若是要修改,請配置 <dubbo:parameter key="hash.arguments" value="0,1" />
缺省用 160 份虛擬節點,若是要修改,請配置 <dubbo:parameter key="hash.nodes" value="320" />
2.17 服務降級
當服務器壓力劇增的狀況下,根據實際業務狀況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放服務器資源以保證核心交易正常運做或高效運做。
可使用屏蔽消費者返回爲空,也能夠是容錯,可是容錯是在失敗以後纔會調用
2.18 集羣容錯
在集羣調用失敗時,Dubbo 提供了多種容錯方案,缺省爲 failover 重試。
集羣容錯模式
Failover Cluster
失敗自動切換,當出現失敗,重試其它服務器。一般用於讀操做,但重試會帶來更長延遲。可經過 retries="2" 來設置重試次數(不含第一次)。
重試次數配置以下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
或
<dubbo:reference>
<dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
Failfast Cluster
快速失敗,只發起一次調用,失敗當即報錯。一般用於非冪等性的寫操做,好比新增記錄。
Failsafe Cluster
失敗安全,出現異常時,直接忽略。一般用於寫入審計日誌等操做。
Failback Cluster
失敗自動恢復,後臺記錄失敗請求,定時重發。一般用於消息通知操做。
Forking Cluster
並行調用多個服務器,只要一個成功即返回。一般用於實時性要求較高的讀操做,但須要浪費更多服務資源。可經過 forks="2" 來設置最大並行數。
Broadcast Cluster
廣播調用全部提供者,逐個調用,任意一臺報錯則報錯 [2]。一般用於通知全部提供者更新緩存或日誌等本地資源信息。
集羣模式配置
按照如下示例在服務提供方和消費方配置集羣模式
<dubbo:service cluster="failsafe" />
或
<dubbo:reference cluster="failsafe" />
整合hystrix見springcloud