微服务下的数据一致性思考

栏目: 后端 · 发布时间: 7年前

内容简介:微服务下的数据一致性思考

之前讲到了数据库层和缓存层的改造思路,而对于业务层的改造,采用了集中式服务转微服务的架构方案。既然是微服务,就意味着面临大量的服务间的内部调用及服务依赖,这就意味着,如果一次请求的调用涉及到两个或多个微服务之间的调用,恰好有下游的微服务调用失败,我们就必须要考虑到回滚及服务间保证数据一致性的问题。所以,今天我将列出可能出现的失败情况及对应的解决方案,希望对大家正在做微服务改造的团队有所帮助。

首先,我们对微服务间调用做一个分类:

  1. 服务间没有直接依赖,采用异步化调用,上游服务完成后,发一个消息异步通知下游服务,下游服务成功与否对上游服务没有影响。

  2. 上游服务弱依赖于某个下游服务的处理结果,可降级。降级时可以不返回这部分的数据。同步调用降级时转为异步。

  3. 上下游微服务强依赖,上游服务依赖于下游服务的返回或者回调,下游必须正常执行,如果下游服务失败了,本次请求判定为失败。

服务间纯异步调用,需保证幂等性和队列重试机制

对于Case1, 只需要考虑2点:幂等性和消息队列重试机制,幂等性意味着,重复消息不会对下游服务的结果产生任何影响;消息队列重试机制保证了,消息本身不会出现丢失,即便消息队列在发给下游队列前挂掉了,重启后,能继续发送对应的消息。

上下游同步执行失败,通过消息执行异步调用

微服务下的数据一致性思考

对于Case2, 采用的方案如下图所示,主服务依赖于A,B,C 三个下游服务,同步调用过程中,服务C调用失败。由于服务C不是强依赖,我们便可以给消息队列发送一条消息,保证主服务可以正常返回,同时保证服务C能继续被执行,保证数据的一致性。

采用TCC进行提交与回滚,保证数据的一致性

Case3是服务间调用最严格的情况,意味着如果下游服务中有一个服务调用失败,上下游的所有服务必须回滚。意味着服务间必须保证同一个事务。业界公认的一个解决方案就是 TCC (Try-Confirm-Cancel) 模式:

  1. 主业务服务分别调用下游业务执行try操作,并在活动管理器中登记所有下游服务。当所有下游微服务的try操作都调用成功,或者某个下游微业务服务的try操作失败。

  2. 业务活动管理器根据第1步的执行结果来执行confirm或cancel操作。如果之前所有try操作都成功,则活动管理器调用所有下游微业务,执行confirm操作。否则调用所有下游微服务的cancel操作。

  3. 如果第2步,执行confirm或concel操作出现失败,活动管理器会启动重试机制,保证所有微服务最终提交或者回滚操作成功。

    微服务下的数据一致性思考

小结

上文对微服务间调用的3种情况的数据一致性方案做了说明:

1. 确保接口幂等性,消息队列具备重试机制,实际上几乎现在所有的MQ都支持重试。

2. 服务调用同步转异步,确保上游服务成功执行,并保证服务间的数据一致性。

3. 利用TCC方案解决服务间调用强依赖的数据一致性。

扫描二维码或手动搜索微信公众号: ForestNotes

欢迎转载,带上以下二维码即可

微服务下的数据一致性思考


以上所述就是小编给大家介绍的《微服务下的数据一致性思考》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ECMAScript6入门

ECMAScript6入门

阮一峰 / 电子工业出版社 / 2014-8 / 49.00元

《ECMAScript6入门》全面介绍了ECMAScript6新引入的语法特性,覆盖了ECMAScript6与ECMAScript5的所有不同之处,对涉及的语法知识给予了详细介绍,并给出了大量简洁易懂的示例代码。 《ECMAScript6入门》为中级难度,适合已有一定JavaScript语言基础的读者,用来了解这门语言的最新发展;也可当作参考手册,查寻新增的语法点。一起来看看 《ECMAScript6入门》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换