ActiveMQ消息丟失和冪等去重

MQ解決消息重發--做到冪等性

一、MQ消息發送

        

  1、發送端MQ-client(消息生產者:Producer)將消息發送給MQ-server;

  2、MQ-server將消息落地;

  3、MQ-server回ACK給MQ-client(Producer);

  4、MQ-server將消息發送給消息接受端MQ-client(消息消費者:Customer);

  5、MQ-client(Customer)消費接受到消息後發送ACK給MQ-server;

  6、MQ-server將落地消息刪除

 

使用同步模式的時候,有3種狀態保證消息被安全生產,在配置爲1(只保證寫入leader成功)的話,如果剛好leader partition掛了,數據就會丟失。
   還有一種情況可能會丟失消息,就是使用異步模式的時候,當緩衝區滿了,如果配置爲0(還沒有收到確認的情況下,緩衝池一滿,就清空緩衝池裏的消息),數據就會被立即丟棄掉。

在數據生產時避免數據丟失的方法: 只要能避免上述兩種情況,那麼就可以保證消息不會被丟失。
   在同步模式的時候,確認機制設置爲-1,也就是讓消息寫入leader和所有的副本。
   在異步模式下,如果消息發出去了,但還沒有收到確認的時候,緩衝池滿了,在配置文件中設置成不限制阻塞超時的時間,也就說讓生產端一直阻塞,這樣也能保證數據不會丟失。

 

二、消息重複發送原因

  爲了保證消息必達,MQ使用了消息超時、重傳、確認機制。使得消息可能被重複發送,如上圖中,由於網絡不可達原因:3和5中斷,可能導致消息重發。消息生產者a收不到MQ-server的ACK,重複向MQ-server發送消息。MQ-server收不到消息消費者c的ACK,重複向消息消費者c發消息。

 

三、消息重複發送產生的後果

  舉個例子:購買會員卡,上游支付系統負責給用戶扣款,下游系統負責給用戶髮卡,通過MQ異步通知。不管是上半場的ACK丟失,導致MQ收到重複的消息,還是下半場ACK丟失,導致購卡系統收到重複的購卡通知,都可能出現,上游扣了一次錢,下游發了多張卡。

 

四、MQ內部如何做到冪等性的

  對於每條消息,MQ內部生成一個全局唯一、與業務無關的消息ID:inner-msg-id。當MQ-server接收到消息時,先根據inner-msg-id判斷消息是否重複發送,再決定是否將消息落地到DB中。這樣,有了這個inner-msg-id作爲去重的依據就能保證一條消息只能一次落地到DB。

 

五、消息消費者應當如何做到冪等性

  1、對於非冪等性業務且要求實現冪等性業務:生成一個唯一ID標記每一條消息,將消息處理成功和去重日誌通過事物的形式寫入去重表。

  2、對於非冪等性業務可不實現冪等性的業務:權衡去重所花的代價決定是否需要實現冪等性,如:購物會員卡成功,向用戶發送通知短信,發送一次或者多次影響不大。不做冪等性可以省掉寫去重日誌的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章