相信通過上三次的文章,基本都了解了dubbo的一些套路,分布式如何做,注冊中心,admin怎么玩的。其實對dubbo沒有這么深入了解的老鐵,也很多會使用dubbo。但是我們僅僅做到使用就完了嗎?其實并不是的。我們角度僅僅不能滿足使用,深層的意義就是滿足底層遠離和實現(xiàn)機制。
####(一)RPC協(xié)議與使用場景 在一個典型RPC的使用場景中,包含了服務(wù)發(fā)現(xiàn)、負載、容錯、網(wǎng)絡(luò)傳輸、序列化等組件,其中RPC協(xié)議就指明了程序如何進行網(wǎng)絡(luò)傳輸和序列化 。也就是說一個RPC協(xié)議的實現(xiàn)就等于一個非透明的RPC調(diào)用,如何做到的的呢?
紅色部分經(jīng)過了一個線程池,RPC拿到數(shù)據(jù)后不能直接調(diào)用server的方法,必須要經(jīng)過一個線程池。RPC協(xié)議服務(wù)端在進行反序列化,協(xié)議解碼,網(wǎng)絡(luò)傳輸,進行IO操作。如果IO線程去執(zhí)行業(yè)務(wù)方法,業(yè)務(wù)方法本身需要做很多的操作,server的方法性能就非常的慢,導致RPC協(xié)議的IO線程,會被業(yè)務(wù)執(zhí)行的邏輯堵塞,導致大量的客戶端堵塞,最后鏈接掛了。
1.地址:服務(wù)提供者地址 2.端口:協(xié)議指定開放的端口 3.運行服務(wù): – netty – mina – RMI 服務(wù) – servlet 容器(jetty、Tomcat、Jboss) 4.報文編碼:協(xié)議報文編碼 – http 報文編碼 – Dubbo 報文編碼 5.序列化方式: – Hessian2Serialization – DubboSerialization – JavaSerialization – JsonSerialization ####(二)協(xié)議報文編碼 dubbo協(xié)議
協(xié)議的編解碼過程
Dubbo 協(xié)議編解碼實現(xiàn)過程 (源碼來源于dubbo2.5.8 )
1.DubboCodec.encodeRequestData() 116L // 編碼request 2.DecodeableRpcInvocation.decode() 89L // 解碼request 3.DubboCodec.encodeResponseData() 184L // 編碼response 4.DecodeableRpcResult.decode() 73L // 解碼response (三)Dubbo中所支持RPC協(xié)議使用dubbo 支持的RPC協(xié)議列表
名稱 | 實現(xiàn)描述 | 連接描述 | 適用場景 |
---|
dubbo | 傳輸服務(wù): mina, netty(默認), grizzy 序列化: dubbo, hessian2(默認), java, fastjson 自定義報文 | 單個長連接 NIO異步傳輸 | 1.常規(guī)RPC調(diào)用 2.傳輸數(shù)據(jù)量小 3.提供者少于消費者 | rmi | 傳輸:java rmi 服務(wù)序列化:java原生二進制序列化 | 多個短連接 BIO同步傳輸 | 1.常規(guī)RPC調(diào)用 2.與原RMI客戶端集成 3.可傳少量文件 4.不支持防火墻穿透 | hessian | 傳輸服務(wù):servlet容器 序列化:hessian二進制序列化 | 基于Http 協(xié)議傳輸,依懶servlet容器配置 | 1.提供者多于消費者2.可傳大字段和文件 3.跨語言調(diào)用 | http | 傳輸服務(wù):servlet容器 序列化:http表單 | 依懶servlet容器配置 | 數(shù)據(jù)包大小混合 | thrift | 與thrift RPC 實現(xiàn)集成,并在其基礎(chǔ)上修改了報文頭 | 長連接、NIO異步傳輸 |
|
關(guān)于RMI不支持防火墻穿透的補充說明:
原因在于RMI 底層實現(xiàn)中會有兩個端口,一個是固定的用于服務(wù)發(fā)現(xiàn)的注冊端口,另外會生成一個隨機端口用于網(wǎng)絡(luò)傳輸。這個隨機端口就不能在防火墻中提前設(shè)置開放開。所以存在防火墻穿透問題 。
(五)協(xié)議的使用與配置Dubbo框架為了更靈活擴展,其支持多種協(xié)議,用戶只需要在 provider 應(yīng)用中 配置即可
<!--
name: 協(xié)議名稱 dubbo|rmi|hessian|http|
host:本機IP可不填,則系統(tǒng)自動獲取
port:端口、填-1表示系統(tǒng)自動選擇
server:運行服務(wù) mina|netty|grizzy|servlet|jetty
serialization:序列化方式 dubbo|hessian2|java|compactedjava|fastjson
[詳細配置參見dubbo 官網(wǎng) ](http:///books/dubbo-user-book/references/xml/dubbo-protocol.html)
-->
<dubbo:protocol name="dubbo" host="192.168.0.11" port="20880" server="netty"
serialization=“hessian2” charset=“UTF-8” />
PS:dubbo很多協(xié)議都封裝好了,直接xml已配置就ok了,其實并不復(fù)雜,對于底層實現(xiàn)其實就是RPC通信,就是socket沒啥特別的。建議讀下源碼,debug跟蹤下效果體會的更加明顯。
|