文章首發於公眾號:BiggerBoy。歡迎關注。
往期文章推薦
大坑!隱式轉換導致索引失效...
先將服務提供者和服務消費者分別啟動,此時消費方正常消費服務。
api:
public interface IHelloService { Result sayHello(ModelParent param); }
服務提供者:
@Component public class HelloServiceImpl implements IHelloService { @Override public Result sayHello(ModelParent param) { MyDto dto = new MyDto(); dto.setMsg("hello," + param.getName()); return Result.success(dto); } }
服務消費者:
@Service public class MyService { @DubboReference(group = "test",version = "1.0",registry = "registry2") private IHelloService helloService; public Result test(ModelParent param) { return helloService.sayHello(param); } }
過了幾個月,服務B接到產品需求,為了滿足需求,對服務A的IHelloService.sayHello提出新的要求,因為本次需求不涉及服務C、D的改動,所以服務A對該服務還需要滿足服務C、D呼叫時保持老邏輯不變,因此服務A需要格外注意服務的相容性。
注意:這裡說的服務A、B、C...是一個個應用或系統。應用或系統對外提供多種服務,例如使用者服務對外提供使用者資訊查詢服務、使用者註冊服務等。
假設服務A和服務B的開發人員確認完需求後,服務A的開發人員想到的介面升級方案如下:
2.1 在原入參物件中新增欄位。服務C、D對於新增的欄位肯定傳的是null,所以可以用null標識走老邏輯,用其他值比如1標識走新邏輯。
2.2 建立新的入參物件 ModelChildren 增加新欄位,且該入參物件繼承原入參物件。此時又分不同的情況。
a.介面方法入參物件保持原入參物件不變,即,方法簽名不變,仍然是Result sayHello(ModelParent param)。僅需改動有新需求的服務B的程式碼,將入參物件改為新入參物件,由於該物件繼承了原入參物件,所以不會有問題,但服務A需要判斷傳的是父類別 ModelParent 還是子類 ModelChildren,並從子類 ModelChildren 中獲取新欄位。
b.介面方法入參物件改為新入參物件,即,方法簽名修改,入參改為新物件Result sayHello(ModelChildren param)。此時,所有消費該服務的消費方均需要修改,如果消費方不改,消費方呼叫該方法時會拋異常org.apache.dubbo.remoting.RemotingException: Fail to decode request due to:java.lang.IllegalArgumentException:Service not found:com.biggerboy.api.IHelloService, sayHello
方案 | 參數列 | 優點 | 缺點 |
新增方法sayHelloV2 | - | 1.新老邏輯分開,相容老版本2.對本次不涉及的服務消費者友好,因為可以不用改動程式碼繼續使用老方法 | 1.額外建立新的服務方法,對記憶體消耗略微增加(可忽略) |
新增服務IHelloServiceV2 | - | 1.新老邏輯分開,相容老版本2.對本次不涉及的服務消費者友好,因為可以不用改動程式碼繼續使用老服務 | 1.額外建立新的服務,對記憶體消耗略微增加(可忽略) |
修改入參ModelParent增加欄位 | 不變 | 1.相容老版本,對不涉及的服務無影響2.不用新增服務,不會額外消費記憶體 | 1.程式中需使用新增的欄位區分新老邏輯 |
新增入參子類ModelChildren增加欄位並繼承原入參ModelParent | 不變 | 1.相容老版本,對不涉及的服務無影響2.不用新增服務,不會額外消費記憶體3.新增加了入參不會影響其他同樣使用ModelParent作為引數的服務 | 1.程式中需使用新增的欄位區分新老邏輯2.額外建立新的類,對記憶體消耗略微增加(可忽略) |
新增入參子類ModelChildren增加欄位並繼承原入參ModelParent | 改為子類 | 1.不用新增服務,不會額外消費記憶體2.新增加了入參不會影響其他同樣使用ModelParent作為引數的服務 | 1.程式中需使用新增的欄位區分新老邏輯2.額外建立新的類,對記憶體消耗略微增加(可忽略)3.需修改參數列,當方法呼叫鏈較長且使用入參物件作為參數列時,需修改的方法較多4.不相容老版本,本次不涉及的服務消費者也需修改,負責報錯 |
你們公司是如何做的呢?歡迎評論區一起討論~
End