做支付平台的時候。需要實現接受上游支付消息,通知給下游渠道。 針對下游渠道:要實現 按通知次數 遞進 延時通知 下游渠道的支付/簽約/代扣的狀態
可參考微信按照 15/15/30/180/1800/1800/1800/1800/3600 單位s 等5個level去通知下游業務端
當時采用rabbitmq死信隊列實現延時消息的通知: 當一個消息過期后,會自動變成死信。如果消息綁定了dead letter change,那么消息過期后會被轉發到相應隊列。從而實現消息延遲消費
rabbitmq的延時消息分為兩類(https://www.rabbitmq.com/ttl.html):
- per queue message TTL: 隊列中所有消息過期時間一樣,可以通過創建mq時候增加 message-ttl。設置過期時間
- per message TTL:可以為每個消息設置過期時間,可以通過發送消息時候增加 expires。設置過期時間
當兩種都設置的時候,過期時間按照小的生效。最開始采用 per message TTL即每個消息的過期時間不一致。但是發現這樣一個現象
問題:當delay_queue中的消息的過期時間不一致的時候,rabbitmq處理機制從性能角度考慮按照FIFO,當queue頭元素未過期時候,后面即使有已經過期的消息時候,
消息也不會馬上變成死信隊列。而被consumer消費,從而導致了delay_queue消息堆積,消息長時間不被消費的現象。
解決: 采用類似於rocketmq的解決方案。不能級別的延時放在不同queue,即delayMs=1000 一個queue,delayMs=2000 一個queue。這樣保證同一個queue中的消息過期時間一致。
從而解決消息堆積問題。 具體實現很簡單:
-
- 預先創建5個level的queue
- 照延時時間,選擇對應queue投遞即可