Dubbo服務化最佳實踐

分包

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

若是須要,也能夠考慮在 API 包中放置一份 spring 的引用配置,這樣使用方,只需在 spring 加載過程當中引用此配置便可,配置建議放在模塊的包目錄下,以避免衝突,如:com/alibaba/china/xxx/dubbo-reference.xml。算法

粒度

服務接口儘量大粒度,每一個服務方法應表明一個功能,而不是某功能的一個步驟,不然將面臨分佈式事務問題,Dubbo 暫未提供分佈式事務支持。spring

服務接口建議以業務場景爲單位劃分,並對相近業務作抽象,防止接口數量爆炸。shell

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

版本

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

建議使用兩位版本號,由於第三位版本號一般表示兼容升級,只有不兼容時才須要變動服務版本。併發

當不兼容時,先升級一半提供者爲新版本,再將消費者所有升爲新版本,而後將剩下的一半提供者升爲新版本。app

兼容性

服務接口增長方法,或服務模型增長字段,可向後兼容,刪除方法或刪除字段,將不兼容,枚舉類型新增字段也不兼容,需經過變動版本號升級。負載均衡

各協議的兼容性不一樣,參見: 服務協議dom

枚舉值

若是是完備集,能夠用 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用戶手冊

相關文章
相關標籤/搜索