《分佈式系統原理與範型》定義:html
「分佈式系統是若干獨立計算機的集合,這些計算機對於用戶來講就像單個相關係統」前端
分佈式系統(distributed system)是創建在網絡之上的軟件系統。java
隨着互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已沒法應對,分佈式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。node
當網站流量很小時,只需一個應用,將全部功能都部署在一塊兒,以減小部署節點和成本。此時,用於簡化增刪改查工做量的數據訪問框架(ORM)是關鍵。linux
適用於小型網站,小型管理系統,將全部功能都部署到一個功能裏,簡單易用。git
缺點: 1、性能擴展比較難 程序員
2、協同開發問題github
3、不利於升級維護web
當訪問量逐漸增大,單一應用增長機器帶來的加速度愈來愈小,將應用拆成互不相干的幾個應用,以提高效率。此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。算法
經過切分業務來實現各個模塊獨立部署,下降了維護和部署的難度,團隊各司其職更易管理,性能擴展也更方便,更有針對性。
缺點: 公用模塊沒法重複利用,開發性的浪費
當垂直應用愈來愈多,應用之間交互不可避免,將核心業務抽取出來,做爲獨立的服務,逐漸造成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用於提升業務複用及整合的分佈式服務框架(RPC)是關鍵。
當服務愈來愈多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增長一個調度中心基於訪問壓力實時管理集羣容量,提升集羣利用率。此時,用於提升機器利用率的資源調度和治理中心(SOA)[ Service Oriented Architecture]是關鍵。
RPC【Remote Procedure Call】是指遠程過程調用,是一種進程間通訊方式,他是一種技術的思想,而不是規範。它容許程序調用另外一個地址空間(一般是共享網絡的另外一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即程序員不管是調用本地的仍是遠程的函數,本質上編寫的調用代碼基本相同。
RPC兩個核心模塊:通信,序列化。
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現。
官網:
服務提供者(Provider):暴露服務的服務提供方,服務提供者在啓動時,向註冊中心註冊本身提供的服務。
服務消費者(Consumer): 調用遠程服務的服務消費方,服務消費者在啓動時,向註冊中心訂閱本身所需的服務,服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
註冊中心(Registry):註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者
監控中心(Monitor):服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
調用關係說明
服務容器負責啓動,加載,運行服務提供者。
服務提供者在啓動時,向註冊中心註冊本身提供的服務。
服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。
服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
1、下載zookeeper網址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/ |
2、解壓zookeeper解壓運行zkServer.cmd ,初次運行會報錯,沒有zoo.cfg配置文件 |
3、修改zoo.cfg配置文件將conf下的zoo_sample.cfg複製一份更名爲zoo.cfg便可。 注意幾個重要位置: dataDir=./ 臨時數據存儲的目錄(可寫相對路徑) clientPort=2181 zookeeper的端口號 修改完成後再次啓動zookeeper |
4、使用zkCli.cmd測試ls /:列出zookeeper根下保存的全部節點 create –e /atguigu 123:建立一個atguigu節點,值爲123 get /atguigu:獲取/atguigu節點的值 |
dubbo自己並非一個服務軟件。它其實就是一個jar包可以幫你的java程序鏈接到zookeeper,並利用zookeeper消費、提供服務。因此你不用在Linux上啓動什麼dubbo服務。
可是爲了讓用戶更好的管理監控衆多的dubbo服務,官方提供了一個可視化的監控程序,不過這個監控即便不裝也不影響使用。
1、下載dubbo-adminhttps://github.com/apache/incubator-dubbo-ops
|
2、進入目錄,修改dubbo-admin配置修改 src\main\resources\application.properties 指定zookeeper地址
|
3、打包dubbo-adminmvn clean package -Dmaven.test.skip=true |
4、運行dubbo-adminjava -jar dubbo-admin-0.0.1-SNAPSHOT.jar 注意:【有可能控制檯看着啓動了,可是網頁打不開,須要在控制檯按下ctrl+c便可】 默認使用root/root 登錄
|
1、下載jdkhttp://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
不要使用wget命令獲取jdk連接,這是默認不一樣意,致使下載來的jdk壓縮內容錯誤 |
2、上傳到服務器並解壓
|
3、設置環境變量/usr/local/java/jdk1.8.0_171
文件末尾加入下面配置 export JAVA_HOME=/usr/local/java/jdk1.8.0_171 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH
|
4、使環境變量生效&測試JDK
|
1、下載zookeeper網址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/ wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz |
2、解壓
|
3、移動到指定位置並更名爲zookeeper
|
1)-複製以下腳本 #!/bin/bash #chkconfig:2345 20 90 #description:zookeeper #processname:zookeeper ZK_PATH=/usr/local/zookeeper export JAVA_HOME=/usr/local/java/jdk1.8.0_171 case $1 in start) sh $ZK_PATH/bin/zkServer.sh start;; stop) sh $ZK_PATH/bin/zkServer.sh stop;; status) sh $ZK_PATH/bin/zkServer.sh status;; restart) sh $ZK_PATH/bin/zkServer.sh restart;; *) echo "require start|stop|status|restart" ;; esac
2)-把腳本註冊爲Service
3)-增長權限
|
1、初始化zookeeper配置文件拷貝/usr/local/zookeeper/conf/zoo_sample.cfg 到同一個目錄下改個名字叫zoo.cfg
|
2、啓動zookeeper
|
1、下載Tomcat8並解壓https://tomcat.apache.org/download-80.cgi wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.32/bin/apache-tomcat-8.5.32.tar.gz |
2、解壓移動到指定位置
|
3、開機啓動tomcat8
複製以下腳本 #!/bin/bash #chkconfig:2345 21 90 #description:apache-tomcat-8 #processname:apache-tomcat-8 CATALANA_HOME=/opt/apache-tomcat-8.5.32 export JAVA_HOME=/opt/java/jdk1.8.0_171 case $1 in start) echo "Starting Tomcat..." $CATALANA_HOME/bin/startup.sh ;;
stop) echo "Stopping Tomcat..." $CATALANA_HOME/bin/shutdown.sh ;;
restart) echo "Stopping Tomcat..." $CATALANA_HOME/bin/shutdown.sh sleep 2 echo echo "Starting Tomcat..." $CATALANA_HOME/bin/startup.sh ;; *) echo "Usage: tomcat {start|stop|restart}" ;; esac
|
4、註冊服務&添加權限
|
5、啓動服務&訪問tomcat測試
|
dubbo自己並非一個服務軟件。它其實就是一個jar包可以幫你的java程序鏈接到zookeeper,並利用zookeeper消費、提供服務。因此你不用在Linux上啓動什麼dubbo服務。
可是爲了讓用戶更好的管理監控衆多的dubbo服務,官方提供了一個可視化的監控程序,不過這個監控即便不裝也不影響使用。
1、下載dubbo-adminhttps://github.com/apache/incubator-dubbo-ops
|
2、進入目錄,修改dubbo-admin配置修改 src\main\resources\application.properties 指定zookeeper地址
|
3、打包dubbo-adminmvn clean package -Dmaven.test.skip=true |
4、運行dubbo-adminjava -jar dubbo-admin-0.0.1-SNAPSHOT.jar 默認使用root/root 登錄
|
某個電商系統,訂單服務須要調用用戶服務獲取某個用戶的全部地址;
咱們如今 須要建立兩個服務模塊進行測試
模塊 |
功能 |
訂單服務web模塊 |
建立訂單等 |
用戶服務service模塊 |
查詢用戶地址等 |
測試預期結果:
訂單服務web模塊在A服務器,用戶服務模塊在B服務器,A能夠遠程調用B的功能。
根據 dubbo《服務化最佳實踐》
建議將服務接口,服務模型,服務異常等均放在 API 包中,由於服務模型及異常也是 API 的一部分,同時,這樣作也符合分包原則:重用發佈等價原則(REP),共同重用原則(CRP)。
若是須要,也能夠考慮在 API 包中放置一份 spring 的引用配置,這樣使用方,只需在 spring 加載過程當中引用此配置便可,配置建議放在模塊的包目錄下,以避免衝突,如:com/alibaba/china/xxx/dubbo-reference.xml。
服務接口儘量大粒度,每一個服務方法應表明一個功能,而不是某功能的一個步驟,不然將面臨分佈式事務問題,Dubbo 暫未提供分佈式事務支持。
服務接口建議以業務場景爲單位劃分,並對相近業務作抽象,防止接口數量爆炸。
不建議使用過於抽象的通用接口,如:Map query(Map),這樣的接口沒有明確語義,會給後期維護帶來不便。
做用:定義公共接口,也能夠導入公共依賴
|
1、Bean模型 public class UserAddress implements Serializable{ } |
3、Service接口UserService public List<UserAddress> getUserAddressList(String userId) |
|
1、pom.xml<dependencies> <dependency> <groupId>com.atguigu.dubbo</groupId> <artifactId>gmall-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> |
2、Servicepublicclass UserServiceImpl implements UserService {
@Override public List<UserAddress> getUserAddressList(String userId) { // TODO Auto-generated method stub returnuserAddressDao.getUserAddressById(userId); }
} |
1、pom.xml<dependencies> <dependency> <groupId>com.atguigu.dubbo</groupId> <artifactId>gmall-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> |
2、測試publicclass OrderService {
UserService userService;
/** * 初始化訂單,查詢用戶的全部地址並返回 * @param userId * @return */ public List<UserAddress> initOrder(String userId){ returnuserService.getUserAddressList(userId); }
} |
如今這樣是沒法進行調用的。咱們gmall-order-web引入了gmall-interface,可是interface的實現是gmall-user,咱們並無引入,並且實際他可能還在別的服務器中。
1、引入dubbo<!-- 引入dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 因爲咱們使用zookeeper做爲註冊中心,因此須要操做zookeeper dubbo 2.6之前的版本引入zkclient操做zookeeper dubbo 2.6及之後的版本引入curator操做zookeeper 下面兩個zk客戶端根據dubbo版本2選1便可 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <!-- curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency>
|
2、配置提供者<!--當前應用的名字 --> <dubbo:applicationname="gmall-user"></dubbo:application> <!--指定註冊中心的地址 --> <dubbo:registryaddress="zookeeper://118.24.44.169:2181"/> <!--使用dubbo協議,將服務暴露在20880端口 --> <dubbo:protocolname="dubbo"port="20880"/> <!-- 指定須要暴露的服務 --> <dubbo:serviceinterface="com.atguigu.gmall.service.UserService" ref="userServiceImpl"/> |
3、啓動服務publicstaticvoid main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-beans.xml");
System.in.read(); } |
1、引入dubbo<!-- 引入dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 因爲咱們使用zookeeper做爲註冊中心,因此須要引入zkclient和curator操做zookeeper --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <!-- curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency>
|
2、配置消費者信息<!-- 應用名 --> <dubbo:applicationname="gmall-order-web"></dubbo:application> <!-- 指定註冊中心地址 --> <dubbo:registryaddress="zookeeper://118.24.44.169:2181"/> <!-- 生成遠程服務代理,能夠和本地bean同樣使用demoService --> <dubbo:referenceid="userService"interface="com.atguigu.gmall.service.UserService"></dubbo:reference> |
訪問gmall-order-web的initOrder請求,會調用UserService獲取用戶地址;
調用成功。說明咱們order已經能夠調用遠程的UserService了;
1、服務提供方<dubbo:applicationname="gmall-user"></dubbo:application> <dubbo:registryaddress="zookeeper://118.24.44.169:2181"/> <dubbo:protocolname="dubbo"port="20880"/> <dubbo:annotationpackage="com.atguigu.gmall.user.impl"/> import com.alibaba.dubbo.config.annotation.Service; import com.atguigu.gmall.bean.UserAddress; import com.atguigu.gmall.service.UserService; import com.atguigu.gmall.user.mapper.UserAddressMapper;
@Service //使用dubbo提供的service註解,註冊暴露服務 publicclass UserServiceImpl implements UserService {
@Autowired UserAddressMapper userAddressMapper; |
2、服務消費方<dubbo:applicationname="gmall-order-web"></dubbo:application> <dubbo:registryaddress="zookeeper://118.24.44.169:2181"/> <dubbo:annotationpackage="com.atguigu.gmall.order.controller"/>
@Controller publicclass OrderController {
@Reference //使用dubbo提供的reference註解引用遠程服務 UserService userService; |
圖形化的服務管理頁面;安裝時須要指定註冊中心地址,便可從註冊中心中獲取到全部的提供者/消費者進行配置管理
簡單的監控中心;
1、下載 dubbo-ops |
2、修改配置指定註冊中心地址進入 dubbo-monitor-simple\src\main\resources\conf 修改 dubbo.properties文件
|
3、打包dubbo-monitor-simplemvn clean package -Dmaven.test.skip=true |
4、解壓 tar.gz 文件,並運行start.bat
若是缺乏servlet-api,自行導入servlet-api再訪問監控中心 |
5、啓動訪問8080
|
全部服務配置鏈接監控中心,進行監控統計 <!-- 監控中心協議,若是爲protocol="registry",表示從註冊中心發現監控中心地址,不然直連監控中心 --> <dubbo:monitorprotocol="registry"></dubbo:monitor>
|
Simple Monitor 掛掉不會影響到 Consumer 和 Provider 之間的調用,因此用於生產環境不會有風險。
Simple Monitor 採用磁盤存儲統計信息,請注意安裝機器的磁盤限制,若是要集羣,建議用mount共享磁盤。
1、引入spring-boot-starter以及dubbo和curator的依賴<dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency> 注意starter版本適配:
|
2、配置application.properties提供者配置:dubbo.application.name=gmall-user application.name就是服務名,不能跟別的dubbo提供端重複 registry.protocol 是指定註冊中心協議 registry.address 是註冊中心的地址加端口號 protocol.name 是分佈式固定是dubbo,不要改。 base-package 註解方式要掃描的包 消費者配置:dubbo.application.name=gmall-order-web |
3、dubbo註解@Service、@Reference 【若是沒有在配置中寫dubbo.scan.base-package,還須要使用@EnableDubbo註解】 |
JVM 啓動 -D 參數優先,這樣可使用戶在部署和啓動時進行參數重寫,好比在啓動時需改變協議的端口。
XML 次之,若是在 XML 中有配置,則 dubbo.properties 中的相應配置項無效。
Properties 最後,至關於缺省值,只有 XML 沒有配置時,dubbo.properties 的相應配置項纔會生效,一般用於共享公共配置,好比應用名。
失敗自動切換,當出現失敗,重試其它服務器,但重試會帶來更長延遲。可經過 retries="2" 來設置重試次數(不含第一次)。
重試次數配置以下: <dubbo:service retries="2" /> 或 <dubbo:reference retries="2" /> 或 <dubbo:reference> <dubbo:method name="findFoo" retries="2" /> </dubbo:reference> |
因爲網絡或服務端不可靠,會致使調用出現一種不肯定的中間狀態(超時)。爲了不超時致使客戶端資源(線程)掛起耗盡,必須設置超時時間。
全局超時配置 <dubbo:consumer timeout="5000" />
指定接口以及特定方法超時配置 <dubbo:reference interface="com.foo.BarService" timeout="2000"> <dubbo:method name="sayHello" timeout="3000" /> </dubbo:reference> |
全局超時配置 <dubbo:provider timeout="5000" />
指定接口以及特定方法超時配置 <dubbo:provider interface="com.foo.BarService" timeout="2000"> <dubbo:method name="sayHello" timeout="3000" /> </dubbo:provider> |
dubbo推薦在Provider上儘可能多配置Consumer端屬性:
1、做服務的提供者,比服務使用方更清楚服務性能參數,如調用的超時時間,合理的重試次數,等等 2、在Provider配置後,Consumer不配置則會使用Provider的配置值,即Provider配置能夠做爲Consumer的缺省值。不然,Consumer會使用Consumer端的全局設置,這對於Provider不可控的,而且每每是不合理的 |
配置的覆蓋規則:
1) 方法級配置別優於接口級別,即小Scope優先
2) Consumer端配置 優於 Provider配置 優於 全局配置,
3) 最後是Dubbo Hard Code的配置值(見配置文檔)
當一個接口實現,出現不兼容升級時,能夠用版本號過渡,版本號不一樣的服務相互間不引用。
能夠按照如下的步驟進行版本遷移:
在低壓力時間段,先升級一半提供者爲新版本
再將全部消費者升級爲新版本
而後將剩下的一半提供者升級爲新版本
老版本服務提供者配置: <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="*" /> |
現象:zookeeper註冊中心宕機,還能夠消費dubbo暴露的服務。
緣由:
健壯性
|
高可用:經過設計,減小系統不能提供服務的時間;
在集羣負載均衡時,Dubbo 提供了多種均衡策略,缺省爲 random 隨機調用。
負載均衡策略
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" /> |
什麼是服務降級?
當服務器壓力劇增的狀況下,根據實際業務狀況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放服務器資源以保證核心交易正常運做或高效運做。
能夠經過服務降級功能臨時屏蔽某個出錯的非關鍵服務,並定義降級後的返回策略。
向註冊中心寫入動態配置覆蓋規則:
RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181")); registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null")); |
其中:
mock=force:return+null 表示消費方對該服務的方法調用都直接返回 null 值,不發起遠程調用。用來屏蔽不重要服務不可用時對調用方的影響。
還能夠改成 mock=fail:return+null 表示消費方對該服務的方法調用在失敗後,再返回 null 值,不拋異常。用來容忍不重要服務不穩定時對調用方的影響。
在集羣調用失敗時,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 旨在經過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具有擁有回退機制和斷路器功能的線程和信號隔離,請求緩存和請求打包,以及監控和配置等功能
spring boot官方提供了對hystrix的集成,直接在pom.xml里加入依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>1.4.4.RELEASE</version> </dependency> |
而後在Application類上增長@EnableHystrix來啓用hystrix starter:
@SpringBootApplication @EnableHystrix public class ProviderApplication {
|
在Dubbo的Provider上增長@HystrixCommand配置,這樣子調用就會通過Hystrix代理。
@Service(version = "1.0.0") public class HelloServiceImpl implements HelloService { @HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") }) @Override public String sayHello(String name) { // System.out.println("async provider received: " + name); // return "annotation: hello, " + name; throw new RuntimeException("Exception to show hystrix enabled."); } } |
對於Consumer端,則能夠增長一層method調用,並在method上配置@HystrixCommand。當調用出錯時,會走到fallbackMethod = "reliable"的調用裏。
@Reference(version = "1.0.0") private HelloService demoService;
@HystrixCommand(fallbackMethod = "reliable") public String doSayHello(String name) { return demoService.sayHello(name); } public String reliable(String name) { return "hystrix fallback value"; } |
一次完整的RPC調用流程(同步調用,異步另說)以下: 1)服務消費方(client)調用以本地調用方式調用服務; 2)client stub接收到調用後負責將方法、參數等組裝成可以進行網絡傳輸的消息體; 3)client stub找到服務地址,並將消息發送到服務端; 4)server stub收到消息後進行解碼; 5)server stub根據解碼結果調用本地的服務; 6)本地服務執行並將結果返回給server stub; 7)server stub將返回結果打包成消息併發送至消費方; 8)client stub接收到消息,並進行解碼; 9)服務消費方獲得最終結果。 RPC框架的目標就是要2~8這些步驟都封裝起來,這些細節對用戶來講是透明的,不可見的。 |
Netty是一個異步事件驅動的網絡應用程序框架, 用於快速開發可維護的高性能協議服務器和客戶端。它極大地簡化並簡化了TCP和UDP套接字服務器等網絡編程。
BIO:(Blocking IO)
NIO (Non-Blocking IO)
Selector 通常稱 爲選擇器 ,也能夠翻譯爲 多路複用器,
Connect(鏈接就緒)、Accept(接受就緒)、Read(讀就緒)、Write(寫就緒)
Netty基本原理:
config 配置層:對外配置接口,以 ServiceConfig, ReferenceConfig 爲中心,能夠直接初始化配置類,也能夠經過 spring 解析配置生成配置類
proxy 服務代理層:服務接口透明代理,生成服務的客戶端 Stub 和服務器端 Skeleton, 以 ServiceProxy 爲中心,擴展接口爲 ProxyFactory
registry 註冊中心層:封裝服務地址的註冊與發現,以服務 URL 爲中心,擴展接口爲 RegistryFactory, Registry, RegistryService
cluster 路由層:封裝多個提供者的路由及負載均衡,並橋接註冊中心,以 Invoker 爲中心,擴展接口爲 Cluster, Directory, Router, LoadBalance
monitor 監控層:RPC 調用次數和調用時間監控,以 Statistics 爲中心,擴展接口爲 MonitorFactory, Monitor, MonitorService
protocol 遠程調用層:封裝 RPC 調用,以 Invocation, Result 爲中心,擴展接口爲 Protocol, Invoker, Exporter
exchange 信息交換層:封裝請求響應模式,同步轉異步,以 Request, Response 爲中心,擴展接口爲 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
transport 網絡傳輸層:抽象 mina 和 netty 爲統一接口,以 Message 爲中心,擴展接口爲 Channel, Transporter, Client, Server, Codec
serialize 數據序列化層:可複用的一些工具,擴展接口爲 Serialization, ObjectInput, ObjectOutput, ThreadPool
單一應用架構:
流動計算架構