1.RPC框架
在java的發展中,隨著業務的越來越龐大,單體架構的工作繁瑣且耦合度高,因此單體架構過渡到了分布式架構,而分布式架構就必然涉及到各個服務之間的遠程通信(RPC框架),RPC框架如圖所示:
工作流程:
a.客戶端調用客戶端Sub(client stub).這個調用是在本地
b.客戶端stub會將要傳輸的參數進行包裝,并通過系統調用發送到服務端機器。打包的過程就叫做序列化。(常見的方式有:XML、JSON、二進制編碼)
c.客戶端本地操作系統發送信息至服務器。(可通過自定義TCP協議或HTTP傳輸)
d.服務器系統將信息傳送至服務端stub(server stub)
e.服務端stub(server stub)解析信息。該過程叫反序列化
f.服務端(server stub)調用程序,并通過類似的方法返回給客戶端
這樣來講:我們調用遠程服務,一是要遵守能夠傳輸的消息格式,二是傳輸的方式,三是調用異常的怎么辦。這些我們客戶端都是不可行自行去管理的,交給RPC框架去處理;
RPC協議正是定義了這樣的一種通信的標準規范,為了滿足不同的場景需求,于是很多標準化的RPC框架就在這個協議的基礎上產生了。
2.dubbo
????????dubbo就是在rpc協議的基礎上誕生的,但是它不僅僅是一個RPC框架,更是一款微服務框架,為大規模微服務時間提供高性能RPC通信、流量治理、可觀測性等解決方案。
思考: 我們講了dubbo的由來,那么dubbo為什么能夠被快速用起來呢? 肯定是解決了一些棘手的問題。
(1) 服務越來越多了,那是不是就說明服務調服務,服務鏈路越來越長了,如何對服務鏈路進行跟蹤和監控呢?
(2)服務通信之間的異常,是否會牽一發而動全身呢?因此我們需要有一種保護機制防止一個節點故障引發大規模的系統故障,就是說要有容錯機制
(3)服務的大規模集群之間是怎么互相發現互相感知的,因此需要有一個注冊中心對服務進行集體管理
(4)服務的大規模集群請求量的分發需要引入負載均衡機制。
3.dubbo特性
dubbo有著一系列高性能的對上述問題的解決方案
a.面向接口代理的高性能RPC調用,服務以接口為粒度,屏蔽了遠程調用底層細節
b.智能負載均衡,內置了多種負載均衡策略,智能感知下游節點健康狀況,顯著減少調用延遲,提高系統吞吐量
c.服務自動注冊與發現,支持多種注冊中心服務,服務實例上下線實時感知
d.可視化的服務治理與運維,提供豐富的服務治理、運維工具。可以隨時查詢服務元數據、服務健康狀況及調用統計,實時下發路由策略,調整配置參數
e.運行期流量調度,內置條件、腳本等路由策略,通過配置不同的路由規則,輕松實現灰度發布,同機房優先等功能。
f.高度可擴展能力,遵循微內核+插件的設計原則,平等對待內置實現和第三方實現。
4.dubbo架構
Provider:暴露服務的服務提供方
Consumer:條用遠程服務的服務消費方
Registry: 服務注冊與發現的注冊中心
Monitor: 統計服務的調用次數和調用時間的監控中心
Container: 服務運行容器
5.demo案例
假設我們有這樣的一個簡單的需求,需要查詢當前用戶還可以領取的優惠券列表。則基于dubbo的實現架構為分析: user為一個獨立部署的服務,coupon也為一個獨立部署的服務。
我們這樣來學習dubbo協議,我們知道dubbo協議是一個遠程網絡通信框架,那么我們user服務如果想要調用到coupon服務,那么我們就需要在user服務中配置conpon服務提供的這個接口url地址才能夠訪問。這就是dubbo的點對點通信。
<!-- 提供方應用信息,用于計算依賴關系 --><dubbo:application name="coupon-portal"/><!-- 使用multicast廣播注冊中心暴露服務地址 --><dubbo:registry address="N/A"/><!-- 用dubbo協議在20880端口暴露服務 --><!-- 聲明需要暴露的服務接口 --><dubbo:referenceinterface="zsc.com.cn.user.IUserService" id="userService"url="dubbo://192.168.36.1:20881/zsc.com.cn.user.IUserService"/>
于是我們使用dubbo協議的這個需求的整個流程就是? 前端訪問--> REST接口->dubbo協議點對點訪問user-api--->user api的實現類---> dubbo協議點對點訪問coupon-api ---> coupon api的實現類-->再將結果返回。
思考: 我們的接口越來越多怎么辦,如果服務是集群部署呢,我們的url也需要配置多個的嗎?如何集體管理這么多個服務? 于是注冊中心就派上了大用場,將這些接口都統一注冊到注冊中心中,其它服務如果引用,去注冊中心上訂閱即可。顯然,從dubbo架構圖中我們可以看出來,dubbo天然就支持服務注冊與發現,目前dubbo能夠支持的注冊中心如consul,etcd,nacos,sofa,zookeeper,eureka,redis等已經很多了。
Springboot有著天生集成dubbo的優勢,那么在springboot中如何使用dubbo;
a.首先引入jar包依賴
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-bom</artifactId><version>${dubbo.version}</version><type>pom</type><scope>import</scope>
</dependency>
spring-boot與dubbo的兼容包以及注冊中心zookeeper包
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-dependencies-zookeeper</artifactId><type>pom</type></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId></dependency>
b.在啟動類上開啟dubbo
c.? dubbo的相關配置(在properties中進行配置)
# 應用名稱
spring.application.name=coupon-service-providerdubbo.application.name=coupon-service# dubbo的協議 -1代表的是端口號隨機生成
dubbo.protocol.port=-1
dubbo.protocol.name=dubbo# 注冊中心 配置中心 元數據中心 id為key
dubbo.registry.id=zk-registry
dubbo.registry.address=zookeeper://192.168.8.133:2181?timeout=20000
dubbo.config-center.address=zookeeper://192.168.8.133:2181?timeout=20000
dubbo.metadata-report.address=zookeeper://192.168.8.133:2181?timeout=20000
d. 服務怎么發布 增加@DubboService注解即可,就會自動進行掃描,并發布到注冊中心
e. 服務怎么引用訂閱 增加@DubboReference 注解即可,就會從注冊中心中引用這個接口
分析: c中我們配置了3個中心地址,registry注冊中心,接口服務url的存儲,config-center 配置中心,這是dubbo的公共配置可以單獨抽取出來(dubbo.properties),metadata 元數據中心,這是dubbo的url過于長的話,把url上攜帶的相關參數進行剝離開來。注冊中心,元數據中心和配置中心都是可以單獨部署的。