前言
明确无法采用修改rabbitMq源码的方式来实现可靠mq。原因有两点:
1、rabbitMq是用erlang语言编写,语言不通
2、公司似乎没有人力专门做这种定制开发
基于以上结论,选择利用关系型数据库来实现可靠mq。例如:要发送的mq数据和业务数据在同一个事务中落库,mq数据落库后,再由另外一个异步线程真正发送mq消息,发送成功则删除数据库中的mq记录。
可选方案
每个微服务数据库建producer和consumer表
优点:
- 隔离,每个业务库有自己表,数据独立存放,不容易相互影响
缺点:
- 消息发送失败,需要分布式任务调度重新发送,每个微服务都需要引入xxl-job
- 每个微服务都有自己的表,不利于维护升级
公用的mq发送/消费数据库
优点:
- 消息的发送和消费记录统一存放在一个库,方便维护升级
- 可以由一个mq管理服务重新发送失败的mq,不需要每个微服务各自引入xxl-job
缺点:
- 所有服务的数据库帐号,都需要有公共库的操作权限
- 当数据库实例拆分的时候,需要在每个实例上都建mq公共库
- 所有服务的mq数据混在一起(影响不大)
类似search-platform的mq-platform
做mq平台的方案,与上面两种差异较大,不再依赖关系型数据库的事务,而是采用“二阶段提交“+“轮询”的方式(模仿网易云音乐mq ,但人家改的是rocketMq源码~)
优点:
- 消息的发送和消费记录统一存放在一个库,方便维护升级
- 可以由一个mq管理服务重新发送失败的mq,不需要每个微服务各自引入xxl-job
- 可实现入侵度较低的mq顺序消费
缺点:
- 方案复杂
- 代码入侵严重,例如:平台的调用者需要实现业务是否完成的接口;在业务数据保存事务之前要调用“预提交”方法,事务结束后,调用“确认提交”或者“回滚”方法