Dubbo服務化最佳實踐


分包

建議將服務接口,服務模型,服務異常等均放在 API 包中,因為服務模型及異常也是 API 的一部分,同時,這樣做也符合分包原則:重用發布等價原則(REP),共同重用原則(CRP)。

如果需要,也可以考慮在 API 包中放置一份 spring 的引用配置,這樣使用方,只需在 spring 加載過程中引用此配置即可,配置建議放在模塊的包目錄下,以免沖突,如:com/alibaba/china/xxx/dubbo-reference.xml。

粒度

服務接口盡可能大粒度,每個服務方法應代表一個功能,而不是某功能的一個步驟,否則將面臨分布式事務問題,Dubbo 暫未提供分布式事務支持。

服務接口建議以業務場景為單位划分,並對相近業務做抽象,防止接口數量爆炸。

不建議使用過於抽象的通用接口,如:Map query(Map),這樣的接口沒有明確語義,會給后期維護帶來不便。

版本

每個接口都應定義版本號,為后續不兼容升級提供可能,如: <dubbo:service interface="com.xxx.XxxService" version="1.0" />。

建議使用兩位版本號,因為第三位版本號通常表示兼容升級,只有不兼容時才需要變更服務版本。

當不兼容時,先升級一半提供者為新版本,再將消費者全部升為新版本,然后將剩下的一半提供者升為新版本。

兼容性

服務接口增加方法,或服務模型增加字段,可向后兼容,刪除方法或刪除字段,將不兼容,枚舉類型新增字段也不兼容,需通過變更版本號升級。

各協議的兼容性不同,參見: 服務協議

枚舉值

如果是完備集,可以用 Enum,比如:ENABLE, DISABLE。

如果是業務種類,以后明顯會有類型增加,不建議用 Enum,可以用 String 代替。

如果是在返回值中用了 Enum,並新增了 Enum 值,建議先升級服務消費方,這樣服務提供方不會返回新值。

如果是在傳入參數中用了 Enum,並新增了 Enum 值,建議先升級服務提供方,這樣服務消費方不會傳入新值。

序列化

服務參數及返回值建議使用 POJO 對象,即通過 setter, getter 方法表示屬性的對象。

服務參數及返回值不建議使用接口,因為數據模型抽象的意義不大,並且序列化需要接口實現類的元信息,並不能起到隱藏實現的意圖。

服務參數及返回值都必需是 byValue 的,而不能是 byReference 的,消費方和提供方的參數或返回值引用並不是同一個,只是值相同,Dubbo 不支持引用遠程對象。

異常

建議使用異常匯報錯誤,而不是返回錯誤碼,異常信息能攜帶更多信息,以及語義更友好。

如果擔心性能問題,在必要時,可以通過 override 掉異常類的 fillInStackTrace() 方法為空方法,使其不拷貝棧信息。

查詢方法不建議拋出 checked 異常,否則調用方在查詢時將過多的 try...catch,並且不能進行有效處理。

服務提供方不應將 DAO 或 SQL 等異常拋給消費方,應在服務實現中對消費方不關心的異常進行包裝,否則可能出現消費方無法反序列化相應異常。

調用

不要只是因為是 Dubbo 調用,而把調用 try...catch 起來。try...catch 應該加上合適的回滾邊界上。

對於輸入參數的校驗邏輯在 Provider 端要有。如有性能上的考慮,服務實現者可以考慮在 API 包上加上服務 Stub 類來完成檢驗。

在 Provider 上盡量多配置 Consumer 端屬性

原因如下:

  • 作服務的提供者,比服務使用方更清楚服務性能參數,如調用的超時時間,合理的重試次數,等等
  • 在 Provider 配置后,Consumer 不配置則會使用 Provider 的配置值,即 Provider 配置可以作為 Consumer 的缺省值 1。否則,Consumer 會使用 Consumer 端的全局設置,這對於 Provider 不可控的,並且往往是不合理的

Provider 上盡量多配置 Consumer 端的屬性,讓 Provider 實現者一開始就思考 Provider 服務特點、服務質量的問題。

示例:

<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" timeout="300" retry="2" loadbalance="random" actives="0"
/>

<dubbo:service interface="com.alibaba.hello.api.WorldService" version="1.0.0" ref="helloService" timeout="300" retry="2" loadbalance="random" actives="0" >
    <dubbo:method name="findAllPerson" timeout="10000" retries="9" loadbalance="leastactive" actives="5" />
<dubbo:service/>

在 Provider 上可以配置的 Consumer 端屬性有:

1.timeout 方法調用超時
2.retries 失敗重試次數,缺省是 2 
3.loadbalance 負載均衡算法 ,缺省是隨機 random。還可以有輪詢 roundrobin、最不活躍優先  leastactive
4.actives 消費者端,最大並發調用限制,即當 Consumer 對一個服務的並發調用到上限后,新調用會 Wait 直到超時 在方法上配置 dubbo:method 則並發限制針對方法,在接口上配置 dubbo:service,則並發限制針對服務

Provider 上配置合理的 Provider 端屬性

<dubbo:protocol threads="200" /> 
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" executes="200" >
    <dubbo:method name="findAllPerson" executes="50" />
</dubbo:service>

Provider 上可以配置的 Provider 端屬性有:

1.threads 服務線程池大小
2.executes 一個服務提供者並行執行請求上限,即當 Provider 對一個服務的並發調用到上限后,新調用會 Wait,這個時候 Consumer可能會超時。在方法上配置 dubbo:method 則並發限制針對方法,在接口上配置 dubbo:service,則並發限制針對服務

配置管理信息

目前有負責人信息和組織信息用於區分站點。有問題時便於的找到服務的負責人,至少寫兩個人以便備份。負責人和組織的信息可以在注冊中心的上看到。

應用配置負責人、組織:

<dubbo:application owner=”ding.lid,william.liangf” organization=”intl” />

service 配置負責人:

<dubbo:service owner=”ding.lid,william.liangf” />

reference 配置負責人:

<dubbo:reference owner=”ding.lid,william.liangf” />

dubbo:service、dubbo:reference 沒有配置負責人,則使用 dubbo:application 設置的負責人。

配置 Dubbo 緩存文件

提供者列表緩存文件:

<dubbo:registry file=”${user.home}/output/dubbo.cache” />

注意:

  1. 文件的路徑,應用可以根據需要調整,保證這個文件不會在發布過程中被清除。
  2. 如果有多個應用進程注意不要使用同一個文件,避免內容被覆蓋。

這個文件會緩存注冊中心的列表和服務提供者列表。有了這項配置后,當應用重啟過程中,Dubbo 注冊中心不可用時則應用會從這個緩存文件讀取服務提供者列表的信息,進一步保證應用可靠性。

監控配置

1.使用固定端口暴露服務,而不要使用隨機端口

這樣在注冊中心推送有延遲的情況下,消費者通過緩存列表也能調用到原地址,保證調用成功。

2.使用 Dragoon 的 http 監控項監控注冊中心上服務提供方

Dragoon 監控服務在注冊中心上的狀態:http://dubbo-reg1.hst.xyi.cn.alidc.net:8080/status/com.alibaba.morgan.member.MemberService:1.0.5 確保注冊中心上有該服務的存在。

3.服務提供方,使用 Dragoon 的 telnet 或 shell 監控項

監控服務提供者端口狀態:echo status | nc -i 1 20880 | grep OK | wc -l,其中的 20880 為服務端口

4.服務消費方,通過將服務強制轉型為 EchoService,並調用 $echo() 測試該服務的提供者是可用

如 assertEqauls(“OK”, ((EchoService)memberService).$echo(“OK”));

不要使用 dubbo.properties 文件配置,推薦使用對應 XML 配置

Dubbo 中所有的配置項都可以配置在 Spring 配置文件中,並且可以針對單個服務配置。

dubbo.properties 中屬性名與 XML 的對應關系

1.應用名 dubbo.application.name

<dubbo:application name="myalibaba" >

2.注冊中心地址 dubbo.registry.address

 <dubbo:registry address="11.22.33.44:9090" >

3.調用超時 dubbo.service.*.timeout
可以在多個配置項設置超時 timeout,由上至下覆蓋(即上面的優先)5,其它的參數(retries、loadbalance、actives等)的覆蓋策略也一樣示例如下:
提供者端特定方法的配置

<dubbo:service interface="com.alibaba.xxx.XxxService" >
     <dubbo:method name="findPerson" timeout="1000" />
</dubbo:service>

提供者端特定接口的配置

<dubbo:service interface="com.alibaba.xxx.XxxService" timeout="200" />

4.服務提供者協議 dubbo.service.protocol、服務的監聽端口 dubbo.service.server.port

<dubbo:protocol name="dubbo" port="20880" />

5.服務線程池大小 dubbo.service.max.thread.threads.size

<dubbo:protocol threads="100" />

6.消費者啟動時,沒有提供者是否拋異常 Fast-Fail alibaba.intl.commons.dubbo.service.allow.no.provider

<dubbo:reference interface="com.alibaba.xxx.XxxService" check="false" />

參考:

dubbo用戶手冊

 


免責聲明!

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



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