掌握之分佈式-1.Dubbo

掌握高併發、高可用架構

第三章 分佈式

本章介紹分佈式架構的底層技術。主要說明面試過程中可能被問到的技術點。

第一節 Dubbo

Duboo 服務治理 Zookeeper

1. Dubbo的概念

Dubbo是一個分佈式、高性能、透明化的RPC(遠程服務調用)服務框架, 提供服務自動註冊、自動發現等高效服務治理方案,可以和Spring無縫集成。

2. Dubbo的由來

111

當網站流量很小時,可以把所有功能都部署在一個項目中,叫單體應用框架。

隨着流量的增大,應用拆分必不可少,此時會出現多個垂直應用,在美格爾應用中處理各自的業務邏輯。

當垂直應用越來越多,應用之間的交互不可避免,將核心業務抽離出來,作爲獨立的服務,逐漸形成穩定的服務中心。此時,用於提高業務複用和整合的 分佈式服務框架 RPC 是關鍵。

當服務越來越多,容量的評估、小服務資源的浪費等問題逐漸顯現,此時需要增加一個調度中心基於訪問壓力實時管理集羣容量,提高集羣利用率。此時,用於提高集羣利用率的 資源調度和治理中心 SOA 是關鍵。

3. Dubbo的主要特點
  • 透明化的遠程方法調用,沒有API侵入
  • 軟負載均衡及容錯機制,降低成本,拒絕單點
  • 服務自動註冊與發現,不再需要寫死服務提供者地址,註冊中心基於接口名查詢服務提供者的IP地址,並能夠平滑的添加或刪除服務提供者
4. Dubbo的核心組件
  • Provider,暴露服務的服務提供方
  • Consumer,調用遠程服務的服務消費者
  • Registry,服務註冊與發現的服務中心
  • Monitor,統計服務的調用次數和調用時間的監控中心
  • Container,服務運行容器

333

640?wx_fmt=png

下面來解釋上述的兩張圖:

  1. 服務容器啓動、加載、運行服務提供者
  2. 服務提供者在啓動時,向註冊中心註冊自己提供的服務
  3. 服務消費者在啓動時,向註冊中心訂閱自己所需的服務,並將獲得的地址列表進行緩存。如果沒有訂閱到自己想訂閱的服務,它會不斷嘗試訂閱
  4. 註冊中心返回服務提供者地址列表給消費者。當新的服務註冊到註冊中心後,註冊中心會基於長連接將這些服務通過notify到消費者
  5. 服務消費者從緩存的提供者地址列表中,基於軟負載均衡算法,選一臺進行服務調用(此處有容錯機制)
  6. 服務提供者和消費者,在各自的內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心
5. Dubbo的核心配置
配置 配置說明
dubbo:service 服務配置,用於暴露服務,定義服務的元信息,一個服務可用多個協議暴露,也可以註冊到多個註冊中心,對應ServiceBean
dubbo:reference 引用配置,用於創建一個遠程服務代理,一個引用可以指向多個註冊中心。對應ReferenceBean
dubbo:protocol 協議配置,用於配置提供服務的協議信息,協議由提供方指定,消費方被動接受。對應ProtocolConfig
dubbo:application 應用配置,用於配置當前應用信息,不管應用是服務提供方還是消費方 。對應ApplicationConfig
dubbo:module 模塊配置,用於配置當前模塊信息,可選。對應ModuleConfig
dubbo:registry 註冊中心配置。對應RegistryConfig
dubbo:monitor 監控中心配置。對應MonitorConfig
dubbo:provider 提供者配置,當沒有配置ProtocolConfigServiceBean時,採用該配置項,可選。對應ProviderConfig
dubbo:consumer 消費方配置,當沒有配置ReferenceBean時,採用該配置項,可選。對應ConsumerConfig
dubbo:method 方法配置
dubbo:argument 參數配置
6. Dubbo支持的協議
協議名稱 實現描述 連接 使用場景
dubbo協議(默認) 傳輸:mina、netty、grizzly<br />序列化:hessian2、java、json 缺省採用單一長連接和NIO異步通信,TCP 1.傳入傳出參數數據包較小<br />2.消費者數量遠大於生產者<br />3.常規遠程服務調用<br />4.不適合傳輸大數據量的服務,比如文件、視頻等
rmi 傳輸:rmi java<br />序列化:java標準序列化 連接個數:多連接<br />連接方式:短連接<br />傳輸協議:TCP/IP<br />傳輸方式:BIO 1.常規RPC調用<br />2.傳入傳出參數大小包混合<br />3.可傳文件<br />4.不支持防火牆穿透<br />5.生產者和消費者數量差不多
hessian 傳輸:servlet容器<br />序列化:hessian2 連接個數:多連接<br />連接方式:短連接<br />傳輸協議:HTTP<br />傳輸方式:同步傳輸 1.生產者的數量比消費者多<br />2.可傳文件<br />3.傳入傳輸參數數據包較大<br />4.跨語言傳輸
http 傳輸:servlet容器<br />序列化:表單序列化JSON<br />採用Spring的httpInvoker實現,基於表單的遠程服務調用 連接個數:多連接<br />連接方式:短連接<br />傳輸協議:HTTP<br />傳輸方式:同步傳輸 1.生產者多餘消費者<br />2.數據包大小混合<br />3.需同時給應用程序和瀏覽器使用的服務
webservice 傳輸:HTTP<br />序列化:SOAP文本序列化 連接個數:多連接<br />連接方式:短連接<br />傳輸協議:HTTP<br />傳輸方式:同步傳輸 1.系統集成<br />2.跨語言傳輸
thrift 與thrift rpc實現集成,並在基礎上修改了報文頭 長連接、NIO異步傳輸
memcached
redis
7.支持的序列化框架

hessian(默認)、dubbo(不建議)、fastjson、Java自帶序列化

8. 支持的通信框架

默認是Netty的NIO通信,還支持mina、Grizzly、Http等

9. 支持的集羣容錯機制
集羣容錯方案 說明
Failover Cluster(默認) 失敗自動切換,自動重試其他服務器
Failfast Cluster 快速失敗,立即報錯,只發起一次調用
Failsafe Cluster 失敗安全,出現異常時,直接忽略
Failback Cluster 失敗自動恢復,記錄失敗請求,定時重發
Forking Cluster 並行調用多個服務器,只要一個成功立即返回
Broadcast Cluster 廣播逐個調用所有生產者,任意一個報錯則報錯

讀操作建議使用Failover失敗自動切換,默認重試兩次

寫操作建議使用Failfast快速失敗,調用一次失敗就報錯

10. 支持的負載均衡算法
負載均衡測量 說明
Random LoadBalance(默認) 隨機,按權重分配隨機概率
RoundRobin LoadBalance 輪詢,按公約後的權重設置輪詢比率
LeastActive LoadBalance 最少活躍調用數,相同活躍數的隨機
ConsistendHash LoadBalance 一致性Hash,相同參數的請求總是發到同一生產者
11. 支持的註冊中心
  • Multicast註冊中心
  • Zookeeper註冊中心
  • Redis註冊中心
  • Simple註冊中心
12. 服務暴露和服務消費的過程

服務暴露:在容器啓動時,按照Spring的加載流程初始化BeanDefinition,把服務提供者解析成ServiceBean。然後調用export()方法進行暴露。(暴露過程相當長,以後慢慢看吧)

img

  1. ServiceBean拿到對外提供服務的實際類ref(如HelloWorldImpl)
  2. 通過ProxyFactorygetInvoker()方法使用ref生成一個AbstractProxyInvoker實例。到這一步就完成了到Invoker的轉換
  3. Invoker轉換爲Exporter,這個根據不同的協議會有不同的實現
    • Dubbo的實現:發生在DubboProtocolexport(),主要是打開socket偵聽服務,並接收客戶端發來的各種請求
    • RMI的實現:發生在RmiProtocolexport()

服務消費,分爲消費端的初始化和服務引用過程。

初始化:

  1. 把服務引用的信息封裝成URL,並註冊到zk中心
  2. 監聽註冊中心服務的上下線
  3. 連接服務提供端,創建NettyClient對象
  4. 將這些信息包裝成DubboInvoker消費端的調用鏈,創建消費端Invoker實例的服務代理並返回

服務引用:

  1. 經過負載均衡策略,調用提供者
  2. 選擇其中一個服務的URL與提供者netty建立連接,使用ProxyFactory創建遠程代理或本地通信的Invoker,並將Invoker發送到netty提供端
  3. 服務提供端接到該Invoker請求後,找到對應的本地Invoker,處理
  4. 獲取異步、同步處理結果
    • 異步調用,不需要立即拿到返回值,使用ExchangeClient.send()
    • 同步調用,需要立即拿到返回值,使用ExchangeClient.request(),返回一個ResponseFuture,一直阻塞到拿到返回值

img

  1. ReferenceBeaninit()方法調用Protocalref()方法生成Invoker實例
  2. Invoker實例轉換成客戶端需要的接口類
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章