dubbo看這一篇就夠了


為什么要有分布式

  近年來微服務、分布式等名詞非常的火,那么我們又為什么要進行系統拆分?如何進行拆分呢?阿里的dubbo作為分布式框架的代表,無疑是推動了整個行業技術的進步。以前中小型公司都是一個war包打天下,所有人在一個系統里面開發時常出現代碼沖突,每次發布都是幾十萬行代碼,甚至幾百萬行代碼了;而把系統拆分成很多個服務的之后,每個人負責一個服務自己選用什么技術都可以,按照功能模塊來解耦,已經是互聯網行業的標配。

如何進行系統拆分

  這個問題可大可小,可以扯到領域驅動模型設計上面上去,說小了也非常簡單。系統拆分分布式系統、拆成多個微服務架構,是要拆很多倫的。第一輪:團隊擴大項目按照模塊拆分成幾個服務,比如說將電商系統拆分成訂單系統、商品系統、用戶系統等等,差不多幾個人維護一個服務。第二輪:后來項目越來越大、業務越來越復雜,可能就要按照功能點划分出去,比如訂單系統又拆分成了購物車系統、價格系統、訂單管理系統,每人維護各自功能的代碼。

多個系統之間的通信

  各個系統之間調用比如可以直接基於httpclient純接口互相通信,但是http接口通信維護起來成本很高,還要考慮超時重試、負載均衡等亂七八糟的問題。這時候就有了dubbo、cloud全家桶這種產品出現了。dubbo說白了就是一個rpc框架,dubbo對本地接口進行代理、跟遠程服務接口進行網絡通信,給你處理掉負載均衡了、服務實例上下線自動感知了、超時重試了,等一大堆問題。

dubbo的工作原理

  第一層:service層,接口層,就是我們開發的提供者和消費者的接口。
  第二層:config層,配置層,主要是對dubbo進行各種配置的。
  第三層:proxy層,服務代理層,對提供者和消費者包一層網絡代理,默認使用javaAssist動態字節碼生成、創建代理類,但是可以通過spi機制自定義代理規則。
  第四層:registry層,服務注冊層,服務啟動后注冊到注冊中心暴露自己的信息,例如ip、port等。負責服務的注冊與發現。初始化時消費者會將提供者的地址等信息拉取到本地緩存,所以注冊中心掛了可以繼續通信。
  第五層:cluster層,集群層,封裝多個服務提供者的路由以及負載均衡,將多個實例組合成一個服務。
  第六層:monitor層,監控層,對rpc接口的調用次數和調用時間進行監控。
  第七層:protocol層,遠程調用層,封裝rpc調用。不同的協議有不同的請求方式,比如http協議就是http://www.xxx.cn.xxx?id=9527的格式
  第八層:exchange層,信息交換層,封裝請求響應模式,同步轉異步。
  第九層:transport層,網絡傳輸層,抽象mina和netty為統一接口。
  第十層:serialize層,數據序列化層。

dubbo的通訊協議與序列化協議

 1)dubbo協議
   默認就是走dubbo協議的,單一長連接,NIO異步通信,基於hessian作為序列化協議。適用的場景就是:傳輸數據量很小(每次請求在100kb以內),但是並發量很高,而高並發量可能每天調用量達到上億次!此時用長連接是最合適的,就是跟每個服務消費者維持一個長連接就可以,可能總共就100個連接。然后后面直接基於長連接NIO異步通信,可以支撐高並發請求。如果是短連接的話,這么多請求服務提供者會扛不住;同時傳輸數據量太大的話,會導致並發能力降低。所以一般建議是傳輸數據量很小,支撐高並發訪問。
 2)rmi協議
   走java二進制序列化,多個短連接,適合消費者和提供者數量差不多,適用於文件的傳輸,一般較少用
 3)hessian協議
   走hessian序列化協議,多個短連接,適用於提供者數量比消費者數量還多,適用於文件的傳輸,一般較少用
 4)http協議
   走json序列化
 5)webservice
   走SOAP文本序列化

dubbo負載均衡如容錯策略

 負載均衡策略,官網介紹了三種 http://dubbo.apache.org/en-us/docs/dev/impls/load-balance.html
  1. random loadbalance
  隨機調用實現負載均衡,可以設置權重來分配流量,一般就用這個默認的就可以了。
  2. roundrobin loadbalance
  輪詢策略,每個機器負載都一樣,但是容易導致性能差的機器負載過高。可以調整權重,讓性能差的機器承載權重小一些。
  3. leastactive loadbalance
  自動感知策略,根據自動感知機器性能來分配流量。
 容錯機制:
  1. failover cluster模式:失敗自動切換,自動重試其他機器,默認就是這個,常見於讀操作。
  2. failsafe cluster模式:出現異常時忽略掉,常用於不重要的接口調用,比如記錄日志。
  3. failbackc cluster模式:失敗了后台自動記錄請求,然后定時重發,比較適合於寫消息隊列這種。
  4. failfast cluster模式:一次調用失敗就立即失敗,常見於寫操作。
  5. forking cluster模式:並行調用多個,有一個成功就立即返回。
  6. broadcacst cluster模式:逐個調用所有的provider。

spi機制

  上面我們說過了通過spi機制來代理的,那spi到底是什么呢?簡單來說就是就是service provider interface(服務提供接口),比如你有一個接口,它有三個實現類,系統運行的時候到底會找到哪個呢?這就需要spi了,根據指定的配置或者是默認的配置,去找到對應的實現類。就好像我們的jdbc接口,需要我們指定masql、或oracge驅動,這其實也是spi的思想。dubbo官網也提供了自定義spi規則的例子。

dubbo的服務治理

  一個大型的分布式架構,各個服務之間的調用鏈路是怎樣的,服務訪問次數以及接口的調用時長,這些東西都必須要做到心中有數的,全都搞定之后,后面才可以來看當前系統的壓力主要在哪里,如何來擴容和優化啊。

服務降級

  比如說服務A調用服務B,結果服務B掛掉了,服務A重試幾次調用服務B,還是不行,直接降級,走一個備用的邏輯,給用戶返回響應。可以將mock修改為true,然后在跟接口同一個路徑下實現一個Mock類,命名規則是接口名稱加Mock后綴。然后在Mock類里實現自己的降級邏輯。

<dubbo:reference id="fooService" interface="com.test.service.FooService"  timeout="10000" check="false" mock="return null"></dubbo:reference>

失敗重試和超時重試

  所謂失敗重試,就是consumer調用provider要是失敗了,比如拋異常了,此時應該是可以重試的,或者調用超時了也可以重試。某個服務的接口,要耗費5s,你這邊不能干等着,你這邊配置了timeout之后,我等待2s,還沒返回,我直接就撤了;設置retries次數,第一次沒請求成功就繼續重試。

<dubbo:reference id="xxxx" interface="xx" check="true" async="false" retries="3" timeout="2000"/>

全局鏈路追蹤

  一個請求過來經過了哪些服務、哪些接口、每個接口花了多長時間、整個請求響應花了多長時間,我們肯定要做到心中有數。像cloud全家桶里面就有這些現成的插件,不過dubbo只是一個單純的RPC框架,這些需要我們自己去實現,想要實現的非常好通常都是一個有實力的大公司的專門團隊才能做的到,一般我們中小型公司不可能做的很完美,但是還是能夠簡單的監測一下這些信息,通過請求頭啊或者aop什么的來實現就夠了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM