分佈式服務框架通常能夠分爲如下幾個部分,算法
(1)RPC基礎層:spring
包括底層通訊框架,如NIO框架、通訊協議,序列化和反序列化協議,性能優化
以及在這幾部分上的封裝,屏蔽底層通訊細節和序列化方式差別服務器
(2)服務發佈/消費:網絡
服務提供者根據消費者請求消息中的接口名,方法名,參數列表等信息,經過Java反射,調用本地的接口實現類;架構
服務消費者將服務提供者發佈的接口封裝成遠程服務調用;併發
(3)服務調用鏈:負載均衡
在服務調用的職責鏈中,經過在調用鏈切面的編碼完成相關的監控和擴展,如負載均衡,服務調用性能統計,調用完成通知,框架
失敗重發等功能異步
(4)服務註冊中心:
註冊中心負責服務的發佈和通知,須要支持服務的平滑上線下線等
(5)服務治理中心:
服務治理中心是一個可視化的模塊,提供對服務的可視化分析和維護,包括服務運行狀態,調用關係和健康度等
下面以Dubbo爲例來分析分佈式服務框架的結構。
(1)系統角色
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
(2)調用關係
服務容器負責啓動,加載,運行服務提供者。
服務提供者在啓動時,向註冊中心註冊本身提供的服務。
服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。
服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
Dubbo的整體架構如圖所示:
框架分層架構中,各個層次的設計要點:
數據序列化層(Serialize):可複用的一些工具,擴展接口爲Serialization、
ObjectInput、ObjectOutput和ThreadPool。
推薦一個交流學習羣:478030634 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多:
(1)協議支持
Dubbo支持多種協議,以下所示:
Thrift協議 Memcached協議 Redis協議
在通訊過程當中,不一樣的服務等級通常對應着不一樣的服務質量,那麼選擇合適的協議即是一件很是重要的事情。你能夠根據你應用的建立來選擇。例如,使用RMI協議,通常會受到防火牆的限制,因此對於外部與內部進行通訊的場景,就不要使用RMI協議,而是基於HTTP協議或者Hessian協議。
(2)默認使用Dubbo協議
鏈接個數:單鏈接
鏈接方式:長鏈接
傳輸協議:TCP
傳輸方式:NIO異步傳輸
序列化:Hessian二進制序列化
適用範圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者沒法壓滿提供者,儘可能不要使用dubbo協議傳輸大文件或超大字符串
使用場景:常規遠程服務方法調用
從上面的適用範圍總結,dubbo適合小數據量大併發的服務調用,以及消費者機器遠大於生產者機器數的狀況,不適合傳輸大數據量的服務好比文件、視頻等,除非請求量很低。
(3)Dubbo源碼模塊圖
Dubbo以包結構來組織各個模塊,各個模塊及其關係,如圖所示:
能夠經過Dubbo的代碼(使用Maven管理)組織,與上面的模塊進行比較。簡單說明各個包的狀況:
(1)服務提供者暴露一個服務的詳細過程
服務提供者暴露服務的主過程:
首先ServiceConfig類拿到對外提供服務的實際類ref(如:HelloWorldImpl),而後經過ProxyFactory類的getInvoker方法使用ref生成一個AbstractProxyInvoker實例,
到這一步就完成具體服務到Invoker的轉化。接下來就是Invoker轉換到Exporter的過程。
Dubbo處理服務暴露的關鍵就在Invoker轉換到Exporter的過程(如上圖中的紅色部分),下面咱們以Dubbo和RMI這兩種典型協議的實現來進行說明:
Dubbo的實現
Dubbo協議的Invoker轉爲Exporter發生在DubboProtocol類的export方法,它主要是打開socket偵聽服務,並接收客戶端發來的各類請求,通信細節由Dubbo本身實現。
RMI的實現
RMI協議的Invoker轉爲Exporter發生在RmiProtocol類的export方法,
它經過Spring或Dubbo或JDK來實現RMI服務,通信細節這一塊由JDK底層來實現,這就省了很多工做量。
(2)服務消費者消費一個服務的詳細過程
服務消費的主過程:
首先ReferenceConfig類的init方法調用Protocol的refer方法生成Invoker實例(如上圖中的紅色部分),這是服務消費的關鍵。
接下來把Invoker轉換爲客戶端須要的接口(如:HelloWorld)。