天天看點

服務化最佳實踐

一、分包分發

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

異常聲明處理是服務調用中不可缺少的部分。通常服務提供方定義明細業務錯誤異常碼,調用方進行捕獲處理。進一步的異正常約我們稍後會具體說明。

二、接口粒度

接口粒度:服務接口盡可能大粒度,每個服務方法應代表一個功能,而不是某功能的一個步驟,否則将面臨分布式事務問題。也就是說同一個操作功能場景盡可能囊括到一個服務裡,減少調用關聯方。

抽象:服務接口建議以業務場景為機關劃分,并對相近業務做抽象,防止接口數量爆炸。不建議使用過于抽象的通用接口,如:

Map query(Map)

,這樣的接口沒有明确語義,會給後期維護帶來不便。

三、服務版本

如果可能,有必要細粒度版本化到服務接口級别,以更好的控制服務疊代更新。

建議使用兩位版本号,因為第三位版本号通常表示相容更新,隻有不相容時才需要變更服務版本。

當不相容時,先更新一半提供者為新版本,再将消費者全部升為新版本,然後将剩下的一半提供者升為新版本。

四、更新相容性

除非是新的功能服務接口,舊的服務更新必須處理接口的向後相容性。

接口增加參數或者傳回值增加字段一般可以相容,涉及修改或者删除則及枚舉類型使用時,則需要通過版本号更新處理。

枚舉值:

如果是完備集,可以用

Enum

,比如:

ENABLE

,

DISABLE

如果是業務種類,以後明顯會有類型增加,不建議用

Enum

,可以用

String

代替。

如果是在傳回值中用了

Enum

,并新增了

Enum

值,建議先更新服務消費方,這樣服務提供方不會傳回新值。

如果是在傳入參數中用了

Enum

,并新增了

Enum

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

五、序列化

服務參數及傳回值建議使用 POJO 對象,即通過

setter

,

getter

方法表示屬性的對象。

服務參數及傳回值都必須是傳值調用,而不能是傳引用調用,消費方和提供方的參數或傳回值引用并不是同一個,隻是值相同。

六、關于調用異常

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

如果擔心性能問題,在必要時,可以通過 override 掉異常類的

fillInStackTrace()

方法為空方法,使其不拷貝棧資訊。

查詢方法不建議抛出受檢異常,否則調用方在查詢時将過多的

try...catch

,并且不能進行有效處理。

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

七、參數檢查過濾

調用方及服務方都應該對輸入參數進行校驗。可以通過統一的攔截方式處理。

如通過檢查空值、參數長度等進行過濾,減少不必要的調用資源消耗及異常隐患,