供应链业务MQ应用场景经验总结 - Go语言中文社区

供应链业务MQ应用场景经验总结


写在前面:做供应链业务一年有余了,这一年里MQ帮我们解决了很多问题,在此做一些经验总结;另外,各个公司消息中间件提供的功能大同小异,最基础的推消息、下游异常重试机制应该是都具备的,本文所述也是建立在这样的能力基础上的~

场景一:削峰填谷,降低响应时间,下游异常自动重试、保证成功

举例:对库存模块而言,入库是一个增量操作,当通过了数据校验之后就理应执行成功,但入库操作常常伴有复杂的写库逻辑及乐观锁冲突,同步模型平均响应时间长,且并发条件下乐观锁冲突失败概率较大;这里就可以引入MQ,将写库操作异步处理,简要流程如下:
在这里插入图片描述
需要注意的是:
1、如果有重复发消息地可能性,MQ下游需要做业务幂等,整条链路要有并发锁保护(redis实现并发悲观锁可参看文章:https://segmentfault.com/a/1190000014270584);

2、如果下游触发异常,中间件一般会自动重试(并发乐观锁冲突自动重试可解决,中间件一般会提供一直重试、重新入队、丢弃消息等模式,需根据具体场景选取,在此不再赘述);如果是非重试能够解决的异常,则需要再监控到异常后,人工介入跳过、修复、补偿;

3、示例情况是上游无写库,如果上游有写库,可能出现发消息与事务写库两个事件状态不一致的情况,一般会有三种情况:

(1)先事务写库,再发消息;当发消息失败时,写库事务已提交,无法回滚;
(2)先发消息,再事务写库;当写库失败时,消息已发送,无法回滚;
(3)写库事务中发消息,如果发消息失败,事务可以回滚,但如果发消息成功后,事务提交时失败(有这种可能),消息也无法回滚;

如果上游无法避免写库时,我们一般采用先事务写库,再发送消息,因为消息中间件作为基础服务,一般是可靠的,很小概率出现发消息失败;如果出现了,有两种处理方式:

(1)发消息失败,返回客户端失败,则需要脚本补偿,回滚上游写库;
(2)发消息失败,只报警,但返回客户端正常,则需要补偿消息;

场景二:异步处理,服务解耦

举例:每一次操作库存后都需要记录业务操作日志,每个Stock(库存服务)接口都需要在完成库存逻辑后,再调用Log(日志服务)记录操作日志;如果采用同步调用模型,Stock服务就与Log服务耦合,依赖于Log服务的实时响应结果,如果Log服务挂了,Stock服务也就挂了,这不是我们期望看到的;这里就可以引入MQ实现核心流程与非核心流程的解耦,简要流程如下:
在这里插入图片描述
这样,上游只需依赖MQ,一般而言,相比下游服务,中间件是更可靠的;通过MQ的能力,如果下游出现问题,主流程不会阻塞,有更多的时间修复,且更易补偿;

场景三:多下游的发布订阅

举例:商品信息作为供应链基础数据,在几乎所有系统都有应用;如果商品信息变更,其他系统就需要接收变更信息,如何通知就是一个问题;同步通知模型会耦合所有下游服务,响应时间长,在增加或减少接收方时,上游代码还需要变更,显然不可行;这里可以采用多个consumer group订阅同一个topic消息方式,异步接收变更事件,在增加或减少接收方时,下游服务consumer group主动订阅或取消订阅商品信息变更topic即可,简要流程如下:
在这里插入图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zhangliangzi/article/details/85038171
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2019-09-04 15:38:19
  • 阅读 ( 1105 )
  • 分类:Go应用

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢