Dubbo學習筆記
Dubbo學習內容
Dubbo發展背景
Dubbo概述
RPC
Zookeeper、Dubbo控制檯的安裝
Dubbo入門例子
Dubbo詳細講解
Dubbo整合spring mvc
Dubbo整合springboot
Dubbo發音:|ˈdʌbəʊ|
Dubbo官方網站:http://dubbo.apache.org/
Dubbo是阿里巴巴開發的,已經貢獻給Apache,並且已經成Apache的頂級開源專案
1. Dubbo的發展背景
文件:http://dubbo.apache.org/zh-cn/docs/user/preface/background.html
隨著網際網路的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分散式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。
1.1 單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。
此時,用於簡化增刪改查工作量的資料訪問框架(ORM)是關鍵。
使用一個web容器(如tomcat),然後使用Servlet/JSP技術,最後選擇一個合適資料庫管理系統來儲存資料(MySQL、Oracle)。
1.2 垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,提升效率的方法之一是將應用拆成互不相干的幾個應用
,以提升效率。
此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。
使用者系統、許可權系統、商品系統、訂單系統、物流系統…
特點:系統獨立部署,每一個系統都有完整的前後端;
問題:各個系統無法做到完全獨立,公共模組無法複用,系統之間通訊比較麻煩;
1.3 分散式服務架構
當垂直應用越來越多,應用之間互動不可避免,這時將核心業務抽取出來,作為獨立的服務
,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。
此時,用於提高業務複用及整合的分散式服務框架(RPC)是關鍵。
分散式架構的難點:
- 各個系統如何進行遠端呼叫
- 如何進行業務拆分
1.4 流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個排程中心基於訪問壓力實時管理叢集容量,提高叢集利用率。此時,用於提高機器利用率的資源排程和治理中心(SOA)是關鍵。
2. RPC
RPC(Remote Procedure Call)- 遠端過程呼叫,它是一種通過網路從遠端計算機程式上請求服務,而不需要了解底層的網路技術協議。RPC假定某種傳輸協議的存在(如TCP),為通訊程式攜帶資料;
通俗的說,RPC可以讓我們像呼叫本地方法一樣呼叫遠端計算機提供的服務;
2.1 RPC的簡單原理
1. 客戶端以本地呼叫的方式呼叫遠端服務
2. client stub接收到呼叫後,將方法、引數等組裝成能夠進行網路傳輸的訊息;
3. client stub查詢服務地址,找到之後,將訊息傳送到服務端;
4. server stub收到訊息之後,對收到的訊息進行解碼;
5. server stub根據解碼結果,使用反射的方式呼叫本地服務;
6. 服務端執行完成之後將結果返回給Server stub;
7. server stub將返回結果打包成訊息併傳送給客戶端;
8. client stub收到訊息後,對結果進行解碼;
總結: 實現RPC的三個技術點
- 服務定址
- 網路連線
- 資料的序列化
3. Dubbo
3.1 Dubbo是什麼
Apache Dubbo™ 是一款高效能Java RPC框架
。
Apache Dubbo |ˈdʌbəʊ| 是一款高效能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠端方法呼叫
,智慧容錯和負載均衡
,以及服務自動註冊和發現
。
3.2 Dubbo作者
從左至右:劉超,樑飛,閭剛,陳雷,劉昊旻,李鼎
3.3 Dubbo的發展歷程
2008年阿里內部開始使用;
2009年初,釋出1.0版本;
2010年初,釋出2.0版本;
2011年10月27日,阿里將Dubbo開源,版本號為2.0.7;
2012年3月,釋出2.1.0版本;
2014年10月,釋出2.3.11版本,之後版本停滯;
2017年9月,阿里重啟維護,重點升級了依賴的JDK版本,釋出2.5.4/2.5.5版本;
2017年10月,釋出2.5.6版本;
2017年11月,釋出2.5.7版本,後期整合了SpringBoot;
2014年10月的時候,噹噹網Fork了Dubbo原始碼,在此基礎上增加了HTTP REST協議,釋出版本號2.8.0,名字叫DubboX
;
網易考拉在Dubbo基礎上開發了DubboK;
3.4 Dubbo架構
-
架構中的角色
Provider:服務提供者
Consumer:服務消費者
Registry:服務註冊和發現的中心
Monitor:監控中心,用於統計服務呼叫情況
Container:Dubbo容器
-
呼叫關係
0、容器負責啟動、載入、執行服務提供者、消費者;
1、服務提供者在啟動時,向註冊中心註冊自己提供的服務;
2、服務消費者在啟動時,向註冊中心訂閱自己需要的服務;
3、註冊中心返回服務提供者的地址列表給消費者;
如果有服務變更(服務的上線或下線),註冊中心會基於長連線的方式推送變更給消費者;
4、服務消費者從地址列表中,基於
軟體負載均衡演算法
,選擇一個服務提供者進行呼叫,如果呼叫失敗,可以重試其它提供者;5、服務消費者和提供者,在記憶體中累計呼叫時間和呼叫次數,每分鐘向監控中心傳送一次統計資料;
4. 安裝單機Zookeeper
4.1 windows版本
-
解壓zookeeper-3.4.12.tar.gz到當前目錄
-
在zookeeper-3.4.12目錄下建立
data
目錄
- 將
zookeeper-3.4.12/conf
目錄下的zoo_sample.cfg
檔案重新命名為zoo.cfg
- 修改
zoo.cfg
檔案中的dataDir
選項
-
啟動zookeeper服務端
雙擊
zookeeper-3.4.12/bin/zkServer.cmd
-
啟動zookeeper的客戶端
雙擊
zookeeper-3.4.12/bin/zkCli.cmd
4.2 Linux安裝
-
將zookeeper-3.4.12.tar.gz上傳到centos的/opt目錄下
-
解壓zookeeper-3.4.12.tar.gz到當前資料夾下(即/opt)
tar -zxf zookeeper-3.4.12.tar.gz -C /opt
-
進入zookeeper-3.4.12,建立一個data目錄
cd zookeeper-3.4.12 mkdir data
-
進入zookeeper-3.4.12/conf目錄,將zoo_sample.cfg修改zoo.cfg
cd conf mv zoo_sample.cfg zoo.cfg
-
編輯zoo.cfg檔案
# 將dataDir修改為../data dataDir=../data
-
啟動ZK server
cd bin ./zkServer.sh start
-
啟動ZK客戶端
./zkCli.sh
5. Dubbo控制檯安裝
-
Dubbo主要用於服務治理
-
可以通過控制檯檢視所有服務(提供者、消費者)
-
可以設定負載均衡、權重調節、服務降級策略等
Dubbo控制檯預設訪問地址:http://localhost:7001
Dubbo預設的使用者名稱/密碼:root/root
在dubbo-admin.jar所在目錄執行 java -jar dubbo-admin.jar
即可(命令列執行)
6. Dubbo入門工程 - Hello World
-
maven依賴
<dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.5</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.13.0</version> </dependency>
-
工程搭建 - maven聚合工程
dubbo-hello dubbo-hello-interface dubbo-hello-provider dubbo-hello-consumer
-
步驟
- 在interface工程建立服務介面
- 在provider工程實現介面
- 在provider工程釋出服務
- 在consumer工程中引用
- 在consumer工程中呼叫遠端服務
Demo
-
首先建立一個聚合工程
其中consumer與provider都需要依賴interface
-
在interface工程建立服務介面 HelloService
public interface HelloService { String hello (String name); }
-
在provider工程實現介面 HelloServiceImpl
public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { System.out.println("hello invoke!"); return "hello" + name; } }
-
在provider工程釋出服務
provider.xml<?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:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!--1.應用名稱--> <dubbo:application name="hello-service"/> <!--2.註冊中心:把dubbo服務註冊到註冊中心--> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!--3.使用dubbo協議在20880埠號釋出服務--> <dubbo:protocol name="dubbo" port="20880" /> <!--4.暴露服務--> <dubbo:service ref="helloService" interface="com.service.HelloService"> </dubbo:service> <!--5.配置服務實現--> <bean id="helloService" class="com.service.impl.HelloServiceImpl" /> </beans>
ProviderTest
public class ProviderTest {
public static void main(String[] args) throws IOException {
new ClassPathXmlApplicationContext("provider.xml");
System.in.read();
}
}
- 在consumer工程中引用
consumer.xml
<?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:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!--1.應用名稱-->
<dubbo:application name="hello-consumer"/>
<!--2.配置註冊中心-->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!--3.引用服務-->
<!--建立了HelloService的代理物件 並註冊成BEAN-->
<dubbo:reference id="helloService" interface="com.etoak.service.HelloService">
</dubbo:reference>
</beans>
- 在consumer工程中呼叫遠端服務
ConsumerTest
public class ConsumerTest {
public static void main(String[] args) throws IOException {
ApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
//獲取遠端服務HelloService的代理物件
HelloService helloService = ioc.getBean(HelloService.class);
//呼叫遠端服務
String result = helloService.hello("Dubbo");
System.out.println(result);
System.in.read();
}
}
7. Dubbo詳解
7.1 Dubbo的註冊中心有哪些
1、Multicast註冊中心
Multicast註冊中心不需要啟動任何中心節點,只要廣播地址一樣,就可以互相發現。
2、Zookeeper註冊中心
Zookeeper 是 Apache Hadoop 的子專案,是一個樹型的目錄服務,
支援變更推送
,適合作為 Dubbo 服務的註冊中心,工業強度較高,可用於生產環境,並推薦使用。3、Redis註冊中心
4、Simple 註冊中心
5、Nacos註冊中心
推薦使用 zookeeper註冊中心
7.2 Dubbo支援的協議
dubbo、rmi、hessian、http、webservice、rest、thrift、memcached、redis、grpc
推薦使用 Dubbo 協議
7.3 Dubbo服務在ZK中的儲存結構
7.4 啟動時檢查
Dubbo預設情況下會在啟動時檢查依賴的服務是否可用,不可用時會丟擲異常,阻止 Spring 初始化完成,以便上線時,能及早發現問題,預設 check="true"
。
7.4.1 關閉單個服務的啟動檢查 - 消費方
可以通過<dubbo:reference check="false"
> 關閉檢查,比如,測試時,有些服務不關心,或者出現了迴圈依賴,必須有一方先啟動;
<dubbo:reference id="helloService" check="false"
interface="com.etoak.service.HelloService">
</dubbo:reference>
7.4.2 關閉所有服務的啟動檢查 - 消費方
<dubbo:consumer check="false" />
7.4.1 關閉註冊中的啟動檢查 - 消費方和提供方
<dubbo:registry address="zookeeper://127.0.0.1:2181"
check="false" />
7.5 配置載入流程
文件地址
此篇文件主要講在應用啟動階段,Dubbo框架如何將所需要的配置採集起來(包括應用配置、註冊中心配置、服務配置等),以完成服務的暴露和引用流程。
7.5.1 配置來源
-
JVM System Properties,-D引數
-
Externalized Configuration,外部化配置 -
ServiceConfig、ReferenceConfig等程式設計介面採集的配置、spring配置
-
本地配置檔案
dubbo.properties
(寫在src/main/resources)配置在classpath根目錄
7.5.2 配置流程
配置載入的優先順序
jvm引數 > 外部化配置 > 程式設計介面、spring配置 > dubbo.properties
Idea中配置jvm引數
7.6 XML配置 - 不同粒度配置的覆蓋關係
- 方法級優先,介面級次之,全域性配置再次之。
- 如果級別一樣,則消費方優先,提供方次之。
-
配置級別
方法級:
<dubbo:method>
介面級:
<dubbo:service>
、<dubbo:reference>
全域性級:
<dubbo:provider>
、<dubbo:consumer>
-
配置優先順序
7.7 直連提供者
在開發及測試環境下,經常需要繞過註冊中心,只測試指定服務提供者,這時候可能需要點對點直連;點對點直連方式,以服務介面為單位,忽略註冊中心的提供者列表,A 介面配置點對點,不影響 B 介面從註冊中心獲取列表。
<dubbo:reference id="helloService"
url="dubbo://127.0.0.1:20880"
interface="com.etoak.service.HelloService">
<dubbo:method name="hello" />
</dubbo:reference>
7.8 本地存根
提供方有些時候想在客戶端也執行部分邏輯,比如:做 ThreadLocal 快取,提前驗證引數,呼叫失敗後偽造容錯資料等等。
實現步驟
-
在服務介面旁邊寫一個名字為
介面名Stub
的服務實現類 -
在這個實現類中新增一個有參的構造方法,構造方法引數就是這個服務介面的代理(也就是可以直接寫這個服務介面)
-
配置服務
<!--這種方式的配置需要命名十分規範 會去找相同資料夾下的serviceNameStub 即:com.etoak.service.HelloServiceStub--> <dubbo:service interface="com.service.HelloService" stub="true" />
<!-- 直接指定stub方式 --> <dubbo:service interface="com.service.HelloService" stub="com.etoak.service.HelloServiceStub" />
-
Demo
/** * 這個程式碼是由提供者邊寫 消費者執行 */ public class HelloServiceStub implements HelloService{ HelloService helloService; //構造方法引數:是真正的遠端代理物件 public HelloServiceStub(HelloService helloService){ this.helloService = helloService; } @Override public String hello(String name) { System.out.println("這行程式碼在客戶端(消費方)執行"); //如果name不為空 if(name != null && ! "".equals(name)){ //發起遠端呼叫 return helloService.hello(name); } //如果為空 則不發起遠端呼叫 return "引數異常"; } }
7.9 服務分組
當一個介面有多種實現時,可以用 group 區分。
-
提供方配置
<dubbo:service ref="helloService" group="service" interface="com.etoak.service.HelloService"> <dubbo:method name="hello" timeout="4000" /> </dubbo:service> <bean id="helloService" class="com.etoak.service.impl.HelloServiceImpl" /> <dubbo:service ref="helloService2" group="service2" interface="com.etoak.service.HelloService"> </dubbo:service> <bean id="helloService2" class="com.etoak.service.impl.HelloService2" />
-
消費方配置
<dubbo:reference id="helloService" group="service2" interface="com.etoak.service.HelloService"> <dubbo:method name="hello" /> </dubbo:reference>
7.10 服務的多版本
當一個介面實現出現不相容需要升級時,可以用版本號過渡,版本號不同的服務相互間不引用。
可以按照以下的步驟進行版本遷移:
- 在低壓力時間段,先升級一半提供者為新版本
- 再將所有消費者升級為新版本
- 然後將剩下的一半提供者升級為新版本
服務端配置方式
<dubbo:service ref="helloService" stub="true"
timeout="6000" retries="5"
version="1.0"
interface="com.etoak.service.HelloService">
</dubbo:service>
消費端配置
<dubbo:reference id="helloService"
timeout="5500"
version="2.0"
interface="com.etoak.service.HelloService">
</dubbo:reference>
7.11 負載均衡
Dubbo 提供了多種均衡策略,預設為 random
隨機呼叫。
1. Random LoadBalance
隨機
,按權重設定隨機概率。
在一個截面上碰撞的概率高,但呼叫量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。
2. RoundRobin LoadBalance
輪詢,按公約後的權重
設定輪詢比率。
存在慢的提供者累積請求的問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。
3. LeastActive LoadBalance
最少活躍呼叫數,相同活躍數的隨機,活躍數指呼叫前後計數差
。
使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。
4. 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” />
控制檯配置
7.12 服務降級
可以通過服務降級
功能臨時遮蔽某個出錯的非關鍵服務,並定義降級後的返回策略。
mock=force:return+null
表示消費方對該服務的方法呼叫都直接返回 null 值,不發起遠端呼叫。用來遮蔽不重要服務不可用時對呼叫方的影響。- 還可以改為
mock=fail:return+null
表示消費方對該服務的方法呼叫失敗後,再返回 null 值,不拋異常。用來容忍不重要服務不穩定時對呼叫方的影響。
8. Dubbo整合springboot
使用者服務 - 根據id查詢使用者資訊
-
建立工程
dubbo-boot dubbo-boot-bean java bean dubbo-boot-interface 服務介面 dubbo-boot-mapper mapper介面 + sql dubbo-boot-user-service 服務實現 springboot dubbo-boot-consumer 消費者 springboot
-
編寫步驟
-
在bean工程建立User,要實現序列化介面
-
在mapper工程中建立UserMapper介面、sql
-
在interface工程定義服務介面UserService
-
在user-service工程編寫服務實現
整合mybatis、dubbo
-
在consumer工程引用UserService服務
整合dubbo
-
啟動springboot測試
先啟動註冊中心
再啟動服務提供者
再啟動消費者
-
Demo
待續…
相關文章
- Dubbo 學習筆記筆記
- dubbo學習筆記---dubbo開發實戰筆記
- Dubbo學習筆記(一) 入門筆記
- Spring boot + Zookeeper + Dubbo學習筆記Springboot筆記
- Dubbo學習筆記(二) Dubbo 控制後臺的安裝筆記
- Dubbo學習小記
- Dubbo 學習筆記(五) 開發環境常用技巧筆記開發環境
- Dubbo學習筆記(一)基本概念與簡單使用筆記
- Dubbo學習筆記(四)叢集容錯與負載均衡筆記負載
- Dubbo筆記(一)筆記
- dubbo學習
- numpy的學習筆記\pandas學習筆記筆記
- Dubbo學習筆記(三) RPC核心原理和執行緒模型筆記RPC執行緒模型
- IT學習筆記筆記
- 學習筆記筆記
- 【學習筆記】數學筆記
- 《JAVA學習指南》學習筆記Java筆記
- Dubbo | Dubbo快速上手筆記 - 環境與配置筆記
- Elasticsearch學習筆記Elasticsearch筆記
- Scala學習筆記筆記
- MySql學習筆記MySql筆記
- jQuery 學習筆記jQuery筆記
- react學習筆記React筆記
- 學習筆記(4.3)筆記
- 學習筆記(4.4)筆記
- 學習筆記(3.29)筆記
- 學習筆記(4.1)筆記
- AOP學習筆記筆記
- AspectJ學習筆記筆記
- 學習筆記(3.27)筆記
- 學習筆記(4.2)筆記
- golang 學習筆記Golang筆記
- Zookeeper學習筆記筆記
- 學習筆記(3.24)筆記
- 學習筆記(3.25)筆記
- 學習筆記(3.21)筆記
- GitHub學習筆記Github筆記
- jest 學習筆記筆記