前言
明確無法採用修改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順序消費
缺點:
- 方案複雜
- 代碼入侵嚴重,例如:平臺的調用者需要實現業務是否完成的接口;在業務數據保存事務之前要調用“預提交”方法,事務結束後,調用“確認提交”或者“回滾”方法