RabbitMQ延迟消息的延迟极限是多少?

以前在写Spring Cloud Stream专题内容的时候,特意介绍了一下如何使用RabbitMQ的延迟消息来实现定时任务。最近正好由于开发碰到了使用过程当中发现,延迟消息没有效果,消息直接就被消费了的状况。所以就继续深刻研究了一下问题缘由,在此记录下来,给碰到相似问题的童鞋们参考。java

问题定位

由于不是全部的消息都出现了没有延迟消息效果的因素,经过有问题的消息特征,大体猜想多是延迟时间过长致使了消息延迟失败。为了验证这个缘由,先拿以前文章中的例子,来测试一下延迟时间是否与问题直接相关。git

对以前的延迟消息使用样例(文末的Git仓库中能够获取完整代码)接口作一下微改,增长了一个请求参数delay来控制延迟时间:github

@GetMapping("/sendMessage")
public String messageWithMQ(@RequestParam String message, @RequestParam Long delay) {
    log.info("Send: " + message);
    testTopic.output().send(MessageBuilder.withPayload(message).setHeader("x-delay", delay).build());
    return "ok";
}

而后尝试发起了两个请求:spring

请求1:延迟5000毫秒。消息发送到MQ以后确实延迟了5秒以后才获得了消费,没有任何问题。app

curl localhost:8080/sendMessage?message=hello&delay=5000

请求2:延迟1年(31536000000毫秒)。消息发送到MQ以后立刻就被消费者消费了,彻底没有延迟效果。curl

curl localhost:8080/sendMessage?message=hello&delay=31536000000

问题小结

在明确了问题缘由以后,须要对该功能的时候作一些明确的限定(延迟时间的极限),以免再次出现相似的问题。深刻探索下去,这里的失败主要与消息的过时时间(TTL)有直接的关系。在RabbitMQ中,消息的过时时间必须是非负 32 位整数,即:0 <= n <= 2^32-1,以毫秒为单位。 其中,2^32-1 = 4294967295。测试

这里咱们能够尝试下面两个请求,分别设置延迟时间为4294967295何4294967296:ui

curl localhost:8080/sendMessage?message=hello&delay=4294967295
curl localhost:8080/sendMessage?message=hello&delay=4294967296

能够发现,当延迟时间为4294967295毫秒的时候,延迟消息工做正常;当延迟时间为4294967296毫秒的时候,消息被直接消费,没有延迟效果。url

因此,咱们在使用RabbitMQ的延迟消息功能时候,必须注意它的延迟极限是4294967295毫秒。若是你的业务需求会超过这个临界值,就必须避开这个坑,采用其余方法来实现须要延迟或者定时执行的任务了。spa

代码示例

本文示例读者能够经过查看下面仓库的中的stream-delayed-message项目:

  • Github: https://github.com/dyc87112/SpringCloud-Learning/tree/master/4-Finchley
  • Gitee: https://gitee.com/didispace/SpringCloud-Learning/tree/master/4-Finchley

若是您对这些感兴趣,欢迎star、follow、收藏、转发给予支持!

相关文章
相关标签/搜索