Dubbo是阿里巴巴SOA服務化治理方案的核心框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。下面我們來看下服務化的最佳實踐。
分包
建議將服務接口、服務模型、服務異常等均放在 API 包中,因為服務模型和異常也是 API 的一部分,這樣做也符合分包原則:重用發佈等價原則(REP),共同重用原則(CRP)。
如果需要,也可以考慮在 API 包中放置一份 Spring 的引用配置,這樣使用方只需在 Spring 加載過程中引用此配置即可。配置建議放在模塊的包目錄下,以免衝突,如:com/alibaba/china/xxx/dubbo-reference.xml。
粒度
服務接口儘可能大粒度,每個服務方法應代表一個功能,而不是某功能的一個步驟,否則將面臨分佈式事務問題,Dubbo 暫未提供分佈式事務支持。
服務接口建議以業務場景為單位劃分,並對相近業務做抽象,防止接口數量爆炸。
不建議使用過於抽象的通用接口,如:Map query(Map),這樣的接口沒有明確語義,會給後期維護帶來不便。
版本
每個接口都應定義版本號,為後續不兼容升級提供可能,如:
<service>
建議使用兩位版本號,因為第三位版本號通常表示兼容升級,只有不兼容時才需要變更服務版本。
當不兼容時,先升級一半提供者為新版本,再將消費者全部升為新版本,然後將剩下的一半提供者升為新版本。
兼容性
服務接口增加方法,或服務模型增加字段,可向後兼容,刪除方法或刪除字段,將不兼容,枚舉類型新增字段也不兼容,需通過變更版本號升級。
各協議的兼容性不同,參見:服務協議
枚舉值
如果是完備集,可以用 Enum,比如:ENABLE, DISABLE。
如果是業務種類,以後明顯會有類型增加,不建議用 Enum,可以用 String 代替。
如果是在返回值中用了 Enum,並新增了 Enum 值,建議先升級服務消費方,這樣服務提供方不會返回新值。
如果是在傳入參數中用了 Enum,並新增了 Enum 值,建議先升級服務提供方,這樣服務消費方不會傳入新值。
序列化
服務參數及返回值建議使用 POJO 對象,即通過 setter, getter 方法表示屬性的對象。
服務參數及返回值不建議使用接口,因為數據模型抽象的意義不大,並且序列化需要接口實現類的元信息,並不能起到隱藏實現的意圖。
服務參數及返回值都必須是傳值調用,而不能是傳引用調用,消費方和提供方的參數或返回值引用並不是同一個,只是值相同,Dubbo 不支持引用遠程對象。
異常
建議使用異常彙報錯誤,而不是返回錯誤碼,異常信息能攜帶更多信息,並且語義更友好。
如果擔心性能問題,在必要時,可以通過 override 掉異常類的 fillInStackTrace() 方法為空方法,使其不拷貝棧信息。
查詢方法不建議拋出 checked 異常,否則調用方在查詢時將過多的 try...catch,並且不能進行有效處理。
服務提供方不應將 DAO 或 SQL 等異常拋給消費方,應在服務實現中對消費方不關心的異常進行包裝,否則可能出現消費方無法反序列化相應異常。
調用
不要只是因為是 Dubbo 調用,而把調用 try...catch 起來。try...catch 應該加上合適的回滾邊界上。
Provider 端需要對輸入參數進行校驗。如有性能上的考慮,服務實現者可以考慮在 API 包上加上服務 Stub 類來完成檢驗。
閱讀更多 技術大咖秀 的文章