MQ 如何實現,消息必達到?
MQ能不能實現消息必達?
要想消息必達,架構設計上有兩個核心設計點:
- 消息落地;
- 消息超時、重傳、確認;
更具體的,要從MQ的架構與流程談起。
MQ的核心架構如何?
如上圖所示,MQ的核心架構圖分為三大塊:
- 發送方 -> 左側粉色部分;
- MQ核心集群 -> 中間藍色部分;
- 接收方 -> 右側黃色部分;
粉色發送方又由兩部分構成:
- 業務調用方;
- MQ-client-sender;
其中,后者向前者提供了兩個核心API:
- SendMsg(bytes[] msg)
- SendCallback()
藍色MQ核心集群由MQ-server,zk,db,管理后臺web等一系列子系統組成。
黃色接收方也由兩部分構成:
- 業務接收方;
- MQ-client-receiver
其中,后者向前者也提供了兩個核心API:
- RecvCallback(bytes[] msg)
- SendAck()
MQ是一個系統間解耦的利器,它能夠很好的解除發布訂閱者之間的耦合,它將上下游的消息投遞解耦成兩個部分,如上述架構圖中的箭頭1和箭頭2:
- 箭頭1,上半場:發送方將消息投遞給MQ;
- 箭頭2,下半場:MQ將消息投遞給接收方;
MQ既然將消息投遞拆成了上下半場,為了保證消息的可靠投遞,上下半場都必須盡量保證消息必達。
上半場,消息投遞流程如何?
MQ消息投遞上半場,流程見上圖123:
- sender將消息發送給MQ-server;
- MQ-server將消息落地;
- MQ-server回調sender;
上半場,如果消息丟了怎么辦?
答:超時與重傳。
MQ上半場的123如果丟失或者超時,sender內置的timer會重發消息,直到收到3。如果重傳N次后還未收到3,則SendCallback向業務方回調發送失敗。
下半場,消息投遞流程如何?
MQ消息投遞下半場,流程見上圖456:
- MQ-server回調reciever;
- reciever收到消息,處理業務邏輯,將ACK發送給MQ-server;
- MQ-server收到ACK,將之前已經落地的消息刪除,流程結束。
下半場,如果消息丟了怎么辦?
答:還是超時與重傳。
MQ下半場的456如果丟失或者超時,MQ-server內置的timer會重發消息,直到收到5并且成功執行6。
上下半場都要超時重發,策略如何?
常見的策略有兩種:
- 定時重發,每隔10秒發一次,直到超出次數;
- 指數退避,先隔x秒重發,2x秒重發,4x秒重發,以此類推;
總結
(1) MQ是系統之間的解耦利器,它能解除消息發送方與接收方的直接耦合;
(2) MQ將消息投遞解耦成了上下兩個半場;
(3) MQ消息必達,架構上有兩個核心設計點:
- 消息落庫
- 消息超時、重傳、確認
未盡事宜
消息重發可能導致收到重復的消息,如何進行架構冪等性設計,下次撰文另述。
知其然,知其所以然。
思路比結論更重要。