Dubbo協議 —— dubbo://(缺省)
dubbo://
Dubbo 缺省協議采用單一長連接和 NIO 異步通訊,適合於小數據量大並發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況。
反之,Dubbo 缺省協議不適合傳送大數據量的服務,比如傳文件,傳視頻等,除非請求量很低。
- Transporter: mina, netty, grizzy
- Serialization: dubbo, hessian2, java, json
- Dispatcher: all, direct, message, execution, connection
- ThreadPool: fixed, cached
特性
缺省協議,使用基於 mina 1.1.7 和 hessian 3.2.1 的 tbremoting 交互。
- 連接個數:單連接
- 連接方式:長連接
- 傳輸協議:TCP
- 傳輸方式:NIO 異步傳輸
- 序列化:Hessian 二進制序列化
- 適用範圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓滿提供者,盡量不要用 dubbo 協議傳輸大文件或超大字符串。
- 適用場景:常規遠程服務方法調用
約束
- 參數及返回值需實現 Serializable 接口
- 參數及返回值不能自定義實現 List, Map, Number, Date, Calendar 等接口,只能用 JDK 自帶的實現,因為 hessian 會做特殊處理,自定義實現類中的屬性值都會丟失。
- Hessian 序列化,只傳成員屬性值和值的類型,不傳方法或靜態變量,兼容情況:
數據通訊 | 情況 | 結果 |
---|---|---|
A->B | 類A多一種 屬性(或者說類B少一種 屬性) | 不拋異常,A多的那 個屬性的值,B沒有, 其他正常 |
A->B | 枚舉A多一種 枚舉(或者說B少一種 枚舉),A使用多 出來的枚舉進行傳輸 | 拋異常 |
A->B | 枚舉A多一種 枚舉(或者說B少一種 枚舉),A不使用 多出來的枚舉進行傳輸 | 不拋異常,B正常接 收數據 |
A->B | A和B的屬性 名相同,但類型不相同 | 拋異常 |
A->B | serialId 不相同 | 正常傳輸 |
接口增加方法,對客戶端無影響,如果該方法不是客戶端需要的,客戶端不需要重新部署。輸入參數和結果集中增加屬性,對客戶端無影響,如果客戶端並不需要新屬性,不用重新部署。
輸入參數和結果集屬性名變化,對客戶端序列化無影響,但是如果客戶端不重新部署,不管輸入還是輸出,屬性名變化的屬性值是獲取不到的。
總結:服務器端和客戶端對領域對象並不需要完全一致,而是按照最大匹配原則。
配置
配置協議:
<dubbo:protocol name="dubbo" port="20880" />
設置默認協議:
<dubbo:provider protocol="dubbo" />
設置服務協議:
<dubbo:service protocol="dubbo" />
多端口:
<dubbo:protocol id="dubbo1" name="dubbo" port="20880" /> <dubbo:protocol id="dubbo2" name="dubbo" port="20881" />
配置協議選項:
<dubbo:protocol name=“dubbo” port=“9090” server=“netty” client=“netty” codec=“dubbo” serialization=“hessian2” charset=“UTF-8” threadpool=“fixed” threads=“100” queues=“0” iothreads=“9” buffer=“8192” accepts=“1000” payload=“8388608” />
多連接配置:
Dubbo 協議缺省每服務每提供者每消費者使用單一長連接,如果數據量較大,可以使用多個連接。
<dubbo:service connections="1"/> <dubbo:reference connections="1"/>
- <dubbo:service connections="0"> 或 <dubbo:reference connections="0"> 表示該服務使用 JVM 共享長連接。缺省
- <dubbo:service connections="1"> 或 <dubbo:reference connections="1"> 表示該服務使用獨立長連接。
- <dubbo:service connections="2"> 或 <dubbo:reference connections="2"> 表示該服務使用獨立兩條長連接。
為防止被大量連接撐掛,可在服務提供方限制TCP最大接收連接數,以實現服務提供方自我保護。
<dubbo:protocol name="dubbo" accepts="1000" />
dubbo.properties 配置:
dubbo.service.protocol=dubbo
常見問題
為什麽要消費者比提供者個數多?
因 dubbo 協議采用單一長連接,假設網絡為千兆網卡 3,根據測試經驗數據每條連接最多只能壓滿 7MByte(不同的環境可能不一樣,供參考),理論上 1 個服務提供者需要 20 個服務消費者才能壓滿網卡。
為什麽不能傳大包?
因 dubbo 協議采用單一長連接,如果每次請求的數據包大小為 500KByte,假設網絡為千兆網卡 3,每條連接最大 7MByte(不同的環境可能不一樣,供參考),單個服務提供者的 TPS(每秒處理事務數)最大為:128MByte / 500KByte = 262。單個消費者調用單個服務提供者的 TPS(每秒處理事務數)最大為:7MByte / 500KByte = 14。如果能接受,可以考慮使用,否則網絡將成為瓶頸。
為什麽采用異步單一長連接?
因為服務的現狀大都是服務提供者少,通常只有幾臺機器,而服務的消費者多,可能整個網站都在訪問該服務,比如 Morgan 的提供者只有 6 臺提供者,卻有上百臺消費者,每天有 1.5 億次調用,如果采用常規的 hessian 服務,服務提供者很容易就被壓跨,通過單一連接,保證單一消費者不會壓死提供者,長連接,減少連接握手驗證等,並使用異步 IO,復用線程池,防止 C10K 問題。
Dubbo協議 —— dubbo://(缺省)