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

2019-07-23 14:05:44 +08:00
 dyc87112

之前在写 Spring Cloud Stream 专题内容的时候,特地介绍了一下如何使用 RabbitMQ 的延迟消息来实现定时任务。最近正好因为开发碰到了使用过程中发现,延迟消息没有效果,消息直接就被消费了的情况。因此就继续深入研究了一下问题原因,在此记录下来,给碰到类似问题的童鞋们参考。

问题定位

因为不是所有的消息都出现了没有延迟消息效果的因素,通过有问题的消息特征,大致猜测可能是延迟时间过长导致了消息延迟失败。为了验证这个原因,先拿之前文章中的例子,来测试一下延迟时间是否与问题直接相关。

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

@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";
}

然后尝试发起了两个请求:

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

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

请求 2:延迟 1 年( 31536000000 毫秒)。消息发送到 MQ 之后马上就被消费者消费了,完全没有延迟效果。

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

问题小结

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

这里我们可以尝试下面两个请求,分别设置延迟时间为 4294967295 何 4294967296:

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

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

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

代码示例

本文示例读者可以通过查看下面仓库的中的 stream-delayed-message 项目:

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

2588 次点击
所在节点    程序员
5 条回复
jakehu
2019-07-23 15:27:24 +08:00
延时消息 beanstalkd 做的不错 https://github.com/beanstalkd/beanstalkd
不过没试过延时一年,哈哈
pubby
2019-07-23 15:33:12 +08:00
@jakehu beanstalkd 的延迟是秒级
julyclyde
2019-07-23 15:58:34 +08:00
curl 的时候,如果后边有 & 符号
建议给 URL 整体加上单引号
qwerthhusn
2019-07-23 17:36:16 +08:00
我们是用的 https://github.com/rabbitmq/rabbitmq-delayed-message-exchange 那个插件。听说 rabbitmq 自带的 ttl 有些问题
vibbow
2019-07-23 23:27:11 +08:00
max value of 32 bit unsigned integer => 4,294,967,295

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/585428

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX