Ban*_*ore 5 java thrift microservices
我们目前正在使用节俭来开发我们的微服务。当我最近遇到以下问题时。
假设下面是摘要对象的节约合同,并且有一个API可使用传递的摘要对象来获取和更新摘要。
版本-1.0
struct Summary {
1: required string summaryId,
2: required i32 summaryCost
}
Summary getSummary(1: string summaryId);
void updateSummary(1: Summary summary);
Run Code Online (Sandbox Code Playgroud)
现在,假设有5个服务正在使用此1.0摘要协议。
在下一发行版中,我们添加另一个对象,该对象称为summaryvalue列表。
所以新合同看起来像
版本-2.0
struct Summary {
1: required string summaryId,
2: required i32 summaryCost,
3: optional list<i32> summaryValues
}
Summary getSummary(1: string summaryId);
void updateSummary(1: Summary summary);
Run Code Online (Sandbox Code Playgroud)
summaryValuesaganist 的列表summaryId。null我们将删除为该“ summaryId”保存的现有值。现在的问题发生时正在使用其他服务较旧的节俭合同(版本1.0版)尝试致电getSummary和updateSummary。
旧客户通过调用updateSummary的意图是为设置另一个值summaryCost。但是,由于此客户端不包含对象,summaryValues因此它将带有summaryValuesnull 的Summary对象发送给Server。
这导致的服务器上删除的所有现有值在summaryValues为summaryId。
有办法省事吗?isSet()方法在这里不起作用,因为它们尝试执行简单的null检查。
每次发布对现有对象进行修改的新客户端时,即使更改与其他服务器无关,我们都必须强制升级其他服务器的客户端版本。
在您的方法version 2.0合同中updateSummary()已更改(即,现在它允许保存和删除汇总值):
选项 1:
不改变其行为,而是创建一种新方法(即updateSummaryV2())并开始在最新版本的客户端中使用它,同时弃用旧方法。
这样,旧版本的客户端仍然使用正常方式,updateSummary()而不会与新方法的合同和假设发生冲突。
选项 2: 添加一个包含 api 版本的可选字段,并将默认值设置为最新的 API 版本:
struct Summary {
1: required string summaryId,
2: required i32 summaryCost,
3: optional list<i32> summaryValues
4: optional i32 apiVersion = 2
}
Run Code Online (Sandbox Code Playgroud)
这样,如果apiVersion未设置,您就知道请求来自旧客户端,对于未来版本,您将知道客户端版本并可以做出相应反应。
或者,如果提供了空列表,您只能删除记录,如果未设置列表,则不执行任何操作,以遵守先前的方法约定。
附带说明一下:即使不考虑交叉兼容性问题,操作依赖于隐含的东西(此处为缺少列表)通常也可能存在风险。当此类操作依赖于显式标志时,通常更安全(并且更易于使用和维护)。
| 归档时间: |
|
| 查看次数: |
1516 次 |
| 最近记录: |