Dubbo與Zookeeper簡單理解
- 2021 年 10 月 4 日
- 筆記
- springboot, 分散式
理論
在《分散式系統原理與范型》一書中有如下定義:「分散式系統是若干獨立電腦的集合,這些電腦對於用戶來說就像單個相關係統 」;
分散式系統是由一組通過網路進行通訊、為了完成共同的任務而協調工作的電腦節點組成的系統。分散式系統的出現是為了用廉價的、普通的機器完成單個電腦無法完成的計算、存儲任務。其目的是利用更多的機器,處理更多的數據。
分散式系統(distributed system)是建立在網路之上的軟體系統。
首先需要明確的是,只有當單個節點的處理能力無法滿足日益增長的計算、存儲任務的時候,且硬體的提升(加記憶體、加磁碟、使用更好的CPU)高昂到得不償失的時候,應用程式也不能進一步優化的時候,我們才需要考慮分散式系統。因為,分散式系統要解決的問題本身就是和單機系統一樣的,而由於分散式系統多節點、通過網路通訊的拓撲結構,會引入很多單機系統沒有的問題,為了解決這些問題又會引入更多的機制、協議,帶來更多的問題。。。
Dubbo
隨著互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分散式服務架構以及流動計算架構勢在必行,急需一個治理系統確保架構有條不紊的演進。
在Dubbo的官網文檔有這樣一張圖
單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,用於簡化增刪改查工作量的數據訪問框架(ORM)是關鍵。
適用於小型網站,小型管理系統,將所有功能都部署到一個功能里,簡單易用。缺點:
1、性能擴展比較難
2、協同開發問題
3、不利於升級維護
垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。此時,用於加速前端頁面開發的Web框架(MVC)是關鍵。
通過切分業務來實現各個模組獨立部署,降低了維護和部署的難度,團隊各司其職更易管理,性能擴展也更方便,更有針對性。
缺點:公用模組無法重複利用,開發性的浪費
分散式服務架構
當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用於提高業務復用及整合的分散式服務框架(RPC)是關鍵。
流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基於訪問壓力實時管理集群容量,提高集群利用率。此時,用於提高機器利用率的資源調度和治理中心(SOA)[ Service Oriented Architecture]是關鍵。
RPC
什麼是RPC?
RPC【Remote Procedure Call】是指遠程過程調用,是一種進程間通訊方式,他是一種技術的思想,而不是規範。它允許程式調用另一個地址空間(通常是共享網路的另一台機器上)的過程或函數,而不用程式設計師顯式編碼這個遠程調用的細節。即程式設計師無論是調用本地的還是遠程的函數,本質上編寫的調用程式碼基本相同。
也就是說兩台伺服器A,B,一個應用部署在A伺服器上,想要調用B伺服器上應用提供的函數/方法,由於不在一個記憶體空間,不能直接調用,需要通過網路來表達調用的語義和傳達調用的數據。為什麼要用RPC呢?就是無法在一個進程內,甚至一個電腦內通過本地調用的方式完成的需求,比如不同的系統間的通訊,甚至不同的組織間的通訊,由於計算能力需要橫向擴展,需要在多台機器組成的集群上部署應用。RPC就是要像調用本地的函數一樣去調遠程函數;
推薦閱讀文章: //www.jianshu.com/p/2accc2840a1b
RPC基本原理
步驟解析
RPC兩個核心模組:通訊,序列化。
序列化的作用 : 數據傳輸需要轉換,
Dubbo與Zookeeper的安裝
什麼是dubbo?
Apache Dubbo | dxbou|是一款高性能、輕量級的開源Jdva RPC框架,它提供了三大核心能力:面向介面的遠程方法調用,智慧容錯和負載均衡,以及服務自動註冊和發現。
dubbo官網: Apache Dubbo
-
了解Dubbo的特性
-
查看官方文檔dubbo基本概念
Dubbo基本概念
服務提供者(Provider) : 暴露服務的服務提供方,服務提供者在啟動時,向註冊中心註冊自己提供的服務。
服務消費者(Consumer) : 調用遠程服務的服務消費方,服務消費者在啟動時,向註冊中心訂閱自己所需的服務,服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
註冊中心(Registry) : 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者
監控中心(Monitor) : 服務消費者和提供者,在記憶體中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
調用關係說明
- 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
- 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
- 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
- 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一台提供者進行調用,如果調用失敗,再選另一台調用。
- 服務消費者和提供者,在記憶體中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
Dubbo環境搭建
點進dubbo官方文檔,推薦我們使用 Zookeeper 註冊中心 | Apache Dubbo
什麼是zookeeper呢?可以查看官方文檔
windows下載zookeeper
-
下載zooleeper Apache ZooKeeper
-
運行/bin/zkServer.cmd 初次運行會報錯,沒有zoo.cfg配置文件; 可能遇到問題:閃退!
-
解決方案:編輯zkServer.cmd文件末尾添加pause。這樣運行出錯就不會退出,會提示錯誤資訊,方便找到原因。
windows下載dubbo-admin
dubbo-admin :是一個監控管理後台查看我們註冊了哪些服務,哪些服務被消費了
dubbo本身並不是一個服務軟體。它其實就是一個jar包,能夠幫你的jiava程式連接到zookeeper,並利用zookeeper消費、提供服務。
但是為了讓用戶更好的管理監控眾多的dubbo服務,官方提供了一個可視化的監控程式dubbo-admin,不過這個監控即使不裝也不影響使用。
- 下載dubbo-admin
地址 : //github.com/apache/dubbo-admin/tree/master
- 解壓進入目錄
修改 dubbo-admin\src\main\resources \application.properties 指定 zookeeper 地址
- 在項目目錄下打包dubbo-admin
mvn clean package -Dmaven.test.skip-true
報錯選這個
mvn package
第一次打包的過程有點慢,需要耐心等待! 直到成功!
- 執行dubbo-admin\target 下的dubbo-admin-0.0.1-SNAPSHOT.jar
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
【注意:zookeeper的服務一定要打開! 】
-
執行完畢,我們去訪問一下http:/localhost:7001/
-
這時候我們需要輸入登錄賬戶和密碼,我們都是默認的root-root
-
登錄成功後,查看介面
SpringBoot + Dubbo + zookeeper
步驟
- 提供者提供服務
- 導入依賴
- 配置註冊中心的地址,以及服務發現名,和要掃描的包
- 在想要被註冊的服務上面~增加一個註解 @Service
- 消費者如何消費
- 導入依賴
- 配置註冊中心的地址,配置自己的服務名
- 從遠程注入服務 @Reference
需要的jar包:
Dubbo + zookeeper
zkclient
坑
排除日誌的包 不然會衝突
依賴
<!--dubbo依賴-->
<!-- //mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.6</version>
</dependency>
<!--zookeeper客戶端依賴-->
<!-- //mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>``
</dependency>
<!--日誌衝突-->
<!-- 引入zookeeper -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
<!--排除這個slf4j-log4j12-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
提供者配置文件
server:
port: 8001
dubbo:
application:
name: provider-server #提供者名字
registry:
address: zookeeper://127.0.0.1:2181 #zookeeper註冊中心地址
scan:
base-packages: com.knight.service #需要註冊
protocol:
name: dubbo
port: 20880 #如果要實現負載均衡效果,修改這裡的埠,如果不配置,會顯示埠佔用
負載均衡的例子配置,與上面的提供者實現負載均衡,只需要修改兩處埠號即可
server:
port: 8002
dubbo:
application:
name: provider-server #提供者名字
registry:
address: zookeeper://127.0.0.1:2181 #zookeeper註冊中心地址
scan:
base-packages: com.knight.service #需要註冊的包
protocol:
name: dubbo
port: 20881
消費者的配置
server:
port: 9001
dubbo:
application:
name: consumer-server
registry:
address: zookeeper://127.0.0.1:2181
提供者例子
@Component //這裡相當於正常的@Service,避免與dubbo的@Service混了,建議用@Component
@Service //注意,此處的service註解是dubbo的
public class TicketServiceImpl implements TicketService{
@Value("${server.port}")
private String port;
@Override
public String getTicket() {
return "《德魯大叔》"+port;
}
}
消費者調用提供者的例子,這裡的TicketService介面的路徑和提供者一致,不需要實現,即消費者和提供者的介面都是在com.*.service這個路徑下,否則會找不到
@Service
public class UserService {
//獲得provider提供的票
//想拿到provider提供的方法,要去註冊中心拿到服務
@Reference //兩種方法拿到註冊中心的服務,1、pom坐標,2,定義路徑相同的介面名
private TicketService ticketService;
public String getTicket(){
return ticketService.getTicket();
}
}