rabbitMq实现支付消息通知
做支付平台的时候。需要实现接受上游支付消息,通知给下游渠道。 针对下游渠道:要实现 按通知次数 递进 延时通知 下游渠道的支付/签约/代扣的状态
可参考微信按照 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投递即可