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