参考:https://blog.csdn.net/shanchahua123456/article/details/84781638数据库
幂等性,有序性,补偿性,可查性并发
保证同种服务集群读写同一个数据库/数据库中间件,这样即便是集群服务,也能够正常确认,由于同种服务集群共用相同的数据。异步
流程高并发
1 上游程序/数据库(生产者): spa
1.1 本地事务 【生成惟一ID——》执行业务流程 ——》 本地保存消息数据(db_queue 表) ——》发送到MQ】 .net
本地db_queue 表:消息ID,相关单据编号,路由键(目标MQ-QUEUE),内容Json,时间,状态。设计
MQ采用confirm方式发送,会有异步的返回结果。根据返回结果,而后更新db_queue表里的消息状态"已发"。3d
本地事务中任意异常都会回滚,但小几率出现 MQ发送成功,可是本地事务未提交。因此下游消费时,要确认上游业务已完成。如果简单的数据传输/同步则不须要确认,由于上游无数据,下游也不会拉取到数据。中间件
1.2 确认接口(幂等):回写业务表状态,删除db_queue 表。 (成功/失败) blog
下游服务消费出现逻辑失败。好比库存不足,金额不足等。此时生产者要视状况手动实现业务回滚逻辑 。若调用了多个下游服务,则可能还要经过MQ通知其余下游服务执行回滚逻辑。
1.3 查询接口:状态业务表、db_queue 表查询等。知足恢复功能和下游服务的查询功能。
2 消息恢复功能(定时任务):(注意幂等性设计)
本服务主要作的是定时补偿工做。
2.1查询db_queue 表,上游程序超时未发送,重发;
2.2查询db_queue 表,上游程序超时未确认数据,调用下游消费者查询接口,若下游已消费则调用上游确认接口,若下游未消费则重发。
3 下游程序/数据库(消费者):(注意幂等性设计)
监听MQ队列:调用对应消费服务
3.1 根据业务判断是否须要查询上游业务已完成,避免无效重试。(数据传输不须要)
3.2 本地事务 【 幂等执行业务流程 ——》 用上游接口,确认上游业务数据 】
3.3 注意MQ的可靠消费,手动ACK,限制收取量
3.4 数据库幂等设计能够依靠:主键/惟一索引/update+条件/先查再写(高并发必定几率有问题)
3.5 查询接口:查询消费状态。
推荐参考文章:RabbitMQ消息可靠性投递解决方案
https://blog.csdn.net/shanchahua123456/article/details/86188705