1. 程式人生 > >001-dubbo基礎-001-服務化最佳實踐、異常處理邏輯

001-dubbo基礎-001-服務化最佳實踐、異常處理邏輯

1、參看地址

  http://dubbo.apache.org/zh-cn/

2、服務化最佳實踐

分包

建議將服務介面、服務模型、服務異常等均放在 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,比如:ENABLEDISABLE

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

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

如果是在傳入引數中用了 Enum,並新增了 Enum

 值,建議先升級服務提供方,這樣服務消費方不會傳入新值。

序列化

服務引數及返回值建議使用 POJO 物件,即通過 settergetter 方法表示屬性的物件。

服務引數及返回值不建議使用介面,因為資料模型抽象的意義不大,並且序列化需要介面實現類的元資訊,並不能起到隱藏實現的意圖。

服務引數及返回值都必需是傳值呼叫,而不能是傳引用呼叫,消費方和提供方的引數或返回值引用並不是同一個,只是值相同,Dubbo 不支援引用遠端物件。

異常

建議使用異常彙報錯誤,而不是返回錯誤碼,異常資訊能攜帶更多資訊,並且語義更友好。

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

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

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

呼叫

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

Provider 端需要對輸入引數進行校驗。如有效能上的考慮,服務實現者可以考慮在 API 包上加上服務 Stub 類來完成檢驗。

3、異常處理邏輯

dubbo的異常處理類是com.alibaba.dubbo.rpc.filter.ExceptionFilter 類,歸納下對異常的處理分為下面幾類:

1)如果provider實現了GenericService介面,直接丟擲

2)如果是checked異常,直接丟擲

3)在方法簽名上有宣告,直接丟擲

4)異常類和介面類在同一jar包裡,直接丟擲

5)是JDK自帶的異常,直接丟擲

6)是Dubbo本身的異常,直接丟擲

7)否則,包裝成RuntimeException拋給客戶端【為了防止客戶端反序列化失敗】