1. 程式人生 > >Dubbo進階

Dubbo進階

# 註冊中心zookeeper 什麼是註冊中心: 註冊中心就是用來儲存服務資訊的地方,就像房屋中介一樣; 為什麼需要註冊中心: 在前面的例子中我們使用了客戶端與伺服器直連的方式完成了服務的呼叫,在實際開發中這回帶來一些問題,例如伺服器地址變更了,或服務搭建了叢集,客戶端不知道服務的地址,此時註冊中心就派上用場了,服務提供方釋出服務後將服務資訊放在zookeeper中,然後消費方從zookeeper獲取伺服器資訊,進行呼叫,這樣就使提供方和消費方解開了耦合,也讓服務提供方可以更方便的搭建叢集; 使用: 1.啟動zookeeper,單機和叢集都可以 2.在雙方配置檔案中指定註冊中心的資訊(內容相同) ```xml ``` 需要說明的是,註冊中心不是必須使用zookeeper,dubbo還支援其他三種:Simple,Redis,Multicast,因其優秀的可用性,官方推薦使用zookeeper; # Dubbo的其他配置方式 ## API配置 簡單的說就是不使用配置檔案而是使用使用程式碼來完成配置,該方式主要用於測試環境或整合其他框架,不推薦用於生產環境; 服務提供者: ```java public class ProviderApplication { public static void main(String[] args) throws IOException { // xmlConfig(); apiConfig(); System.in.read();//阻塞主執行緒保持執行 } private static void apiConfig() { //應用配置 ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("my-service"); applicationConfig.setQosEnable(true); //註冊中心 RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setProtocol("zookeeper"); registryConfig.setAddress("10.211.55.6:2181,10.211.55.7:2181"); //rpc協議 ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setPort(20880); //釋出服務 ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setApplication(applicationConfig); serviceConfig.setProtocol(protocolConfig); serviceConfig.setRegistry(registryConfig); serviceConfig.setInterface(HelloService.class); serviceConfig.setRef(new HelloServiceImpl()); serviceConfig.export(); } ``` 消費者: ```java public class ConsumerApplication { public static void main(String[] args) { // xmlConfig(); apiConfig(); } private static void apiConfig() { //應用配置 ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("my-consumer"); applicationConfig.setQosEnable(false); //註冊中心 RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setProtocol("zookeeper"); registryConfig.setAddress("10.211.55.6:2181,10.211.55.7:2181"); //呼叫服務 ReferenceConfig serviceReferenceConfig = new ReferenceConfig(); serviceReferenceConfig.setApplication(applicationConfig); serviceReferenceConfig.setRegistry(registryConfig); serviceReferenceConfig.setInterface(HelloService.class); HelloService service = serviceReferenceConfig.get(); String tom = service.sayHello("tom"); System.out.println(tom); } ``` ## 註解配置 註解配置是使用較多的一種方式,可加快開發速度,讓我們從繁瑣的配置檔案中解脫出來; Dubbo使用了Spring容器來管理bean,所以配置方式也大同小異,可使用Configuration將一個類作為配置類;在該類中提供必要的幾個bean ### 服務提供者 配置類: ```java @Configuration @EnableDubbo(scanBasePackages = "com.yyh.service") public class ProviderConfiguration { //無論如何配置我們最終需要的還是那幾個bean @Bean public ApplicationConfig applicationConfig(){ //應用配置 ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("my-service"); applicationConfig.setQosEnable(true); return applicationConfig; } @Bean public RegistryConfig registryConfig(){ RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setProtocol("zookeeper"); registryConfig.setAddress("10.211.55.6:2181,10.211.55.7:2181"); return registryConfig; } @Bean public ProtocolConfig protocolConfig(){ //rpc協議 ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setPort(20880); return protocolConfig; } } ``` 服務實現類: ```java //注意該註解是Dubbo提供的 不要用錯 @Service public class HelloServiceImpl implements HelloService { public String sayHello(String name) { return "hello: "+name; } } ``` 釋出服務: ```java public static void main(String[] args) throws IOException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); context.start(); System.in.read();//阻塞主執行緒保持執行 } ``` ### 消費者 配置類: ```java @Configuration @EnableDubbo @ComponentScan("com.yyh.consumer") public class ConsumerConfiguration { @Bean public ApplicationConfig applicationConfig(){ //應用配置 ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("my-consumer"); applicationConfig.setQosEnable(true); return applicationConfig; } @Bean public RegistryConfig registryConfig(){ RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setProtocol("zookeeper"); registryConfig.setAddress("10.211.55.6:2181,10.211.55.7:2181"); return registryConfig; } } ``` 消費者類: ```java @Component public class SayHelloConsumer { @Reference private HelloService helloService; public void sayHello(){ String jack = helloService.sayHello("jack"); System.out.println(jack); } } ``` 執行測試: ```java public class ConsumerApplication { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); SayHelloConsumer consumer = context.getBean(SayHelloConsumer.class); consumer.sayHello(); } ``` 可以發現消費者不需要指定ProtocolConfig,主要服務端固定埠即可; ## 使用properties配置 相比xml和api的方式,properties是體量是最輕的,在面對一些簡單配置時可以採用properties ### 服務提供者 在resource下提供名為`dubbo.properties`的檔案,內容如下: ```properties dubbo.application.name=my-service dubbo.application.owner=jerry dubbo.protocol.dubbo.port=1099 dubbo.registry.address=zookeeper://10.211.55.6:2181 ``` 配置類: ```java @Configuration @EnableDubbo(scanBasePackages = "com.yyh.service") @PropertySource("classpath:/dubbo.properties") public class AnnotationAndPropperties { } ``` 測試程式碼: ```java public class ProviderApplication { public static void main(String[] args) throws IOException { annotationAndPropConfig(); System.out.println("服務已啟動 按任意鍵退出"); System.in.read();//阻塞 主執行緒 保持執行 } private static void annotationAndPropConfig() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationAndPropperties.class); context.start(); } } ``` ### 消費者 同樣提供properties檔案,但不需要指定protocol ```properties dubbo.application.name=my-service dubbo.application.qos.enable=false dubbo.application.owner=jerry dubbo.registry.address=zookeeper://10.211.55.6:2181 ``` 配置類: ```java @EnableDubbo @Configuration @ComponentScan("com.yyh.consumer") @PropertySource("classpath:/dubbo.properties") public class AnnotationAndPropConfiguration { } ``` 消費者類: ```java @Component public class SayHelloConsumer { @Reference private HelloService helloService; public void sayHello(){ String jack = helloService.sayHello("jack"); System.out.println(jack); } } ``` 測試類: ```java public class ConsumerApplication { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); SayHelloConsumer consumer = context.getBean(SayHelloConsumer.class); consumer.sayHello(); } ``` 強調:註解使用時,掃描服務的實現類使用dubbo提供的EnableDubbo註解,而掃描其他bean用的是spring的ComponentScan註解; # 常用配置項 ## 1.啟動時檢查 預設情況下,dubbo在啟動時會自動檢查依賴(作為消費者)的服務是否可用,若服務不可用則直接丟擲異常並阻止容器正常初始化,但在一些情況下我們會希望先啟動程式,因為服務可能會在之後的時間裡變為可用的; ### 啟動檢查註冊中心 ```xml
``` ### 啟動檢查服務提供方(對所有提供者) ```xml ``` ### 啟動檢查服務提供方(對某個提供者) ```xml ``` properties檔案寫法: ```properties java -Ddubbo.reference.com.foo.BarService.check=false #強制修改所有reference的check java -Ddubbo.reference.check=false #當reference的check為空時有效 java -Ddubbo.consumer.check=false java -Ddubbo.registry.check=false ``` ## 2.叢集容錯 在後續的使用中我們可能會對某一個服務部署多個示例形成叢集,隨著專案的執行時間越來越常,一些服務節點可能會宕機或是由於網路原因暫時不可用,叢集容錯可指定在呼叫服務失敗時dubbo要採取的行為; dubbo提供以下6種容錯機制: | 策略名稱 | 優點 | 缺點 | 主要應用場景 | | -------------- | -------------------------------- | -------------------------------------- | ---------------------------------------------------- | | failover(預設) | 對呼叫者遮蔽呼叫失敗的資訊 | 額外資源開銷,資源浪費 | 通訊環境良好,併發不高的場景 | | failfast | 業務快速感知失敗狀態進行自主決策 | 產生較多報錯的資訊 | 非冪等性操作,需要快速感知失敗的場景 | | failsafe | 即使失敗了也不會影響核心流程 | 對於失敗的資訊不敏感,需要額外的監控 | 旁路系統,失敗不影響核心流程正確性的場景 | | failback | 失敗自動非同步重試 | 重試任務可能堆積 | 對於實時性要求不高,且不需要返回值的一些非同步操作 | | forking | 並行發起多個呼叫,降低失敗概率 | 消耗額外的機器資源,需要確保操作冪等性 | 資源充足,且對於失敗的容忍度較低,實時性要求高的場景 | | broadcast | 支援對所有的服務提供者進行操作 | 資源消耗很大 | 通知所有提供者更新快取或日誌等本地資源資訊 | **冪等性:指的是每次呼叫都會產生相同的結果,即不會對資料進行寫操作(增刪改)** ### 配置方式: 容錯配置分為兩個粒度:介面級別,方法級別 #### 服務方配置: 服務方配置即將容錯配置放在服務提供方,這樣一來所有消費方就可以使用統一的容錯機制,而不用每個消費方都配一遍; ```xml
``` #### 消費方配置: ```xml ``` ## 3.負載均衡 為了提高系統的可用性,能夠承受更大的併發量,我們會將壓力的服務部署為叢集,但是如果每次請求都交給叢集中的同一個節點,那這個幾點很可能直接就宕了,所以合理的分配任務給叢集中的每一臺機器也是我們必須考慮的事情,好在dubbo已經提供相應的功能,我們只需簡單的配置即可完成負載均衡; dubbo支援的任務分配方式: ### 隨機random 顧名思義,從Provider列表中選擇隨機選擇一個,但是我們可以為Provider指定權重,權重越大的被選中的機率越高,因此對於效能更好的機器應設定更大的權重,反之則反,如果不指定負載均衡,預設使用隨機負載均衡; ### 輪詢roundrobin 即依次呼叫所有Provider,每個Provider輪流處理請求,當然我們也可以指定權重,Provider收到的請求數量比約等於權重比; 效能差的機器可能會累積一堆請求,最終拖慢整個系統; ### 基於活躍數leastactive 每個Provider收到一個請求則將活躍數+1,每處理完成一個請求則活躍數-1,新的請求將會交給活躍數最少的Provider; 簡單的說效能越好的機器將收到更多的請求,反之則反; ### 基於hash一致consistenthash 將根據Provider的 ip 或者其他的資訊為Provider生成一個 hash,並將這個 hash 投射到 [0, 232 - 1] 的圓環上。當有請求時,則使用請求引數計算得出一個hash值。然後查詢第一個大於或等於該 hash 值的快取Provider,並將請求交予該Provider處理。如果當前Provider掛了,則在下一次請求時,為快取項查詢另一個大於其 hash 值的Provider即可。 具體演算法參考:[去官網看看](http://dubbo.apache.org/zh-cn/docs/source_code_guide/loadbalance.html) ### 配置方法: 與容錯配置一樣,我們可以選擇在服務方或是消費方進行設定; 服務方: ```xml
``` 消費方: ```xml ``` ## 直連 即跳過註冊中新直接找服務提供方,必須提前明確服務提供方的地址,所以該方式一般僅用於開發除錯; ```xml ``` ## 僅訂閱 僅訂閱指的是,不釋出服務到註冊中心,只從註冊中心訂閱依賴的服務; 使用場景:當我們要開發一個新的Provider,而這個Provider需要依賴其他Provider時,使用,其目的是避免正在開發的服務釋出後被消費方呼叫,因為開發還未完成,可能造成意想不到的結果; 這就用到了僅訂閱,再搭配直連即可完成開發除錯; ```xml ``` ## 僅註冊 僅註冊指的是,釋出自身服務到註冊中心,但不從註冊中心訂閱依賴的服務; 使用場景: 自身需要對外提供服務,但是依賴的某個服務還在開發除錯總,不能正常提供訪問; ```xml ``` ## 多註冊中心 對於一些大型系統,為了加快響應速度,可能會在不同地區進行部署,例如阿里雲分佈在7個不同城市,有的時候可能因為當地系統還未部署完成,但是仍然需要提供訪問,這是就需要我們將相同的服務註冊到多個不同的註冊中心; 反過來,一些時候當前系統依賴的服務可能部署在不同的註冊中心中,這就需要同時向多個不同的註冊中心訂閱服務; 配置方式也非常簡單,新增額外registry即可; **案例:** 我們在Common模組中建立新的介面`com.yyh.service.UserService`,同時在Provider中實現該介面,最後釋出到註冊中心; ### 釋出到多個註冊中心 ```xml ``` ### 從不同註冊中心訂閱 ```xml

相關推薦

Dubbo一》——RPC協議底層原理

一 RPC協議簡介 在一個典型的RPC的使用場景中,包含了服務發現、負載、容錯、序列化和網路傳輸等元件,其中RPC協議指明瞭程式如何進行序列化和網路傳輸,也就是說一個RPC協議的實現等於一個非透明的RPC呼叫。 簡單來說,分散式框架的核心是RPC框架,RPC框

dubbo--管控臺

  上篇介紹了dubbo的一個入門例項,服務啟動後,我如何檢視自己的服務是否已經啟動,如何檢視是否存在消費者呢?這就需要使用dubbo的管控臺。    材料準備:      jdk-7u76-linu

Dubbo

# 註冊中心zookeeper 什麼是註冊中心: 註冊中心就是用來儲存服務資訊的地方,就像房屋中介一樣; 為什麼需要註冊中心: 在前面的例子中我們使用了客戶端與伺服器直連的方式完成了服務的呼叫,在實際開發中這回帶來一些問題,例如伺服器地址變更了,或服務搭建了叢集,客戶端不知道服務的地址,此時註冊中心就

Eclipse除錯-結合Dubbo除錯例項分析

本文你會掌握的Eclipse進階技能: ● 除錯窗口裡預設顯示多執行緒 ● 根據需要暫停某執行緒,然後在需要時候恢復 ● 使用Expression執行程式碼直觀計算複雜的條件值 ● Step Into(F5) ● Step Ov

Java高階架構師系統之路全套視訊免費獲取(Dubbo、Redis、Netty、zookeeper Spring cloud、分散式、高併發等架構技術)

效能調優 03 Spring原始碼分析 04 Spring MVC原始碼分析 05 Mybatis原始碼解析 06 網際網路分散式架構思維 07 架構開發基礎之

Java專題(二十六) 將近2萬字的Dubbo原理解析,徹底搞懂dubbo

# 前言 ​ 前面我們研究了RPC的原理,市面上有很多基於RPC思想實現的框架,比如有Dubbo。今天就從Dubbo的SPI機制、服務註冊與發現原始碼及網路通訊過程去深入剖析下Dubbo。 # Dubbo架構 ## 概述 Dubbo是阿里巴巴公司開源的一個高效能優秀的服務框架,使得應用可通過高效能的R

mysql(二)之細談索引、分頁與慢日誌

連表 組合索引 rar 偏移量 最小值 num glob 要求 for 索引 1、數據庫索引   數據庫索引是一種數據結構,可以以額外的寫入和存儲空間為代價來提高數據庫表上的數據檢索操作的速度,以維護索引數據結構。索引用於快速定位數據,而無需在每次訪問數據庫表時搜索數據

CSS之路

模式 ant 表格 weight mil 比較 標題 根據 amp 下面主要引用http://www.cnblogs.com/wangfupeng1988/tag/css知多少/ CSS進階筆記: 一、學習CSS的三個突破點 1.瀏覽器如何加載和解析CSS——CSS的5個來

Android 動畫之動畫切換

ram 屏幕 pre 退出 tac 旋轉動畫 utf 轉動 XML 一、Activity切換動畫   在Android開發中,經常會遇到Activity之間切換效果,下面介紹一下,Activity左右滑動切換效果。在Android2.0以後版本,在Activity中添加了

之路(基礎篇) - 011 arduino api基礎手冊

異或 change 可用 算術運算符 chan 程序結構 換算 是否 關閉 arduino 函數 api 程序結構 在Arduino中, 標準的程序入口main函數在內部被定義, 用戶只需要關心以下兩個函數:void setup()void loop()setup() 函數

之路(基礎篇) - 008 SPI數據傳輸(庫函數方法)

ria att clockd == bus 屏蔽 attach serial out 主機端: 1 /********************************* 2 代碼功能:SPI數據傳輸(主機端) 3 引腳說明: 4 SS/CS:片選(高電平屏

之路(基礎篇) - 009 通過底層AVR方法實現SPI數據傳輸

lean oop and return false 進階 from setup pie 主機端: /********************************* 代碼功能:通過底層AVR方法實現SPI數據傳輸(主機端) 創作時間:2016*10*17 使用資源:

之路(基礎篇) - 007 脈沖寬度測量

style 函數 long 最大 void serial 作者 println 電平 1 /********************************* 2 代碼功能:Pulse脈沖寬度測量 3 使用函數: 4 pulseIn(引腳號,脈沖響應電平,

HTML5 系列:indexedDB 數據庫

連接數據庫 function request html5 客戶端 前言在 HTML5 的本地存儲中,有一種叫 indexedDB 的數據庫,該數據庫是一種存儲在客戶端本地的 NoSQL 數據庫,它可以存儲大量的數據。從上篇:HTML5 進階系列:web Storage ,我們知道

C#系列——WebApi 異常處理解決方案(轉)

機制 輸出 ges 如果 但是 rom lba slist 解決 出處:http://www.cnblogs.com/landeanfen/p/5363846.html 閱讀目錄 一、使用異常篩選器捕獲所有異常 二、HttpResponseException自

之路(中級篇) - 018 基於arduino的簡易版智能衣架

檢驗 dig cloc 布線 pin on() -- mage 根據 一. 設備及要求 目的:制作一個可以自動根據事實的天氣的狀況進行對衣架上的衣服進行晾曬。 基礎裝置:可伸縮的晾衣架。 開發環境:Arduino1. 8.1 主控板:Arduino UNO 動力裝置:

小米面經-技術崗(編程小白如何

在哪裏 相交 it公司 小白 來源 代碼行數 多邊形 通知 計算 先介紹下背景,我本科專業是硬件轉軟件方面,所以一開始算法基礎比較差,沒有做過系統設計,為了能得到好的面試機會,我一直都有努力準備,還在網上關註了各種能提高編程能力的攻略,我覺得打好基礎的前提是要找到優質的學習

項目 之 集群環境搭建(一)概述

問題 特點 多臺 cpu 好的 content 成了 系統資源 通過 今天我們說一個不是特別新,但近期今年伴隨大數據熱而比較火的一個技術-集群技術。 什麽是集群技術 集群(Cluster)技術是指一組相互犭蟲立的計算機,利用快速通信網絡組

Android自己定義組件系列【6】——實踐(3)

err ack XML @+ layout apk get ast edi 上一篇《Android自己定義組件系列【5】——進階實踐(2)》繼續對任老師的《可下拉的PinnedHeaderExpandableListView的實現》進行了分析,這一篇計劃中間插一段“知識點

2Python強化訓練之csv|json|xml|excel高

中國股市 excel 如何 Python進階強化訓練之csv|json|xml|excel高如何讀寫csv數據?實際案例我們可以通過http://table.finance.yahoo.com/table.csv?s=000001.sz,這個url獲取中國股市(深市)數據集,它以csv數據格式存儲