消息隊列如何保證消息能百分百成功被消費
目前常用的消息隊列有很多種,如RabbitMQ,ActiveMQ,Kafka...下面以RabbitMQ為例來講如何保證消息隊列中的信息能百分百被消費掉.
其中消費隊列的工作流程如下:
.我們可以再增加一個機制,增加一個確認機制:
流程解釋:
1)訂單服務生產者再投遞消息之前,先把消息持久化到Redis或DB中,建議redis,高性能。消息的狀態為發送中。
2)confirm機制監聽消息是否發送成功?如ack成功消息,刪除redis中此消息。
3)如果nack不成功的消息,這個可以根據自身的業務選擇是否重發此消息。也可以刪除此消息,由自己的業務決定。
4)這邊加了個定時任務,來拉取隔一定時間了,消息狀態還是為發送中的,這個狀態就表明,訂單服務是沒有收到ack成功消息。
5)定時任務會作補償性的投遞消息。這個時候如果MQ回調ack成功接收了,再把redis中此消息刪除
這種方案其實就是加上一個補償機制,不管MQ有沒有真正的接收到,只要緩存redis中的消息還是發送中的狀態,就意味着這個消息沒有成功的投遞出去,也沒有被消費,定時任務啟動時就要重新發送.
當然定時任務那邊我們還可以加上一個補償的次數,如果大於3次,還是沒有收到ack消息,那就直接把消息的狀態設置為【失敗】,由人工去排查到底是為什么?
不過這樣的方案,就會有可能發送多次相同的消息,很有可能MQ已經收到了消息,就是ack消息回調時出現網絡故障,沒有讓生產者收到。那就要要求消費者一定在消費的時候保障冪等性。