分布式部署服务的情况下,由于网络状况不可预期,消息有可能发送成功,但是消费端消费失败;也有可能消息根本没有发出去,如何保证消息是否发送成功是经常遇到的问题。最近有时间研究了一下,具体方法如下图:
表结构设计如下:
具体思路:
正常流程(网络都正常)
1.消息生产方,将消息信息与业务数据在同一个事务中存入数据库。
2.消息发送发,发送消息,消息发送表‘状态’为‘已发送’
3.消息消费方,接收消息,存入消息接收表,并调用生产方接口,更新生产方消息发送表‘状态’为‘已完成’。
正常流程结束。
异常流程
1.消息生产方,将消息信息与业务数据在同一个事务中存入数据库。
2.消息发送发,发送消息,消息发送表‘状态’为‘已发送’
3.消息消费方未收到消息;或,接收到消息,存入消息接收表,但调用生产方接口失败。
4.消息生产方job1,查询消息发送表‘状态’为‘已发送’,并当前时间超过回调截止时间(或过期时间)的记录,然后调用消息消费方查询状态接口
5.消息生产方job1若查到结果,则更新消息发送表‘状态’为‘已完成’,流程结束;若为查到结果,则更新消息发送表‘状态’为‘未发送’
6.消息生产方job2,查询消息发送表‘状态’为‘未发送’的记录,重新生产消息,并更新状态为“已发送”。之后会自动跳转到流程3,直到状态变更为“已完成”。
注意,消息接收表的sourcemsg_id字段需唯一,保证幂等性。
针对这个设计,完成了net core3.1 的demo,用了rabbitmq作为消息队列,mysql作为数据库,ef core orm,redis分布式锁。
demo地址为https://github.com/cysnet/mq-trans.git

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2019-03-28 pyquery
2019-03-28 beautifulsoup
2018-03-28 AutoMapper