RabbitMQ延迟消息的延迟极限是多少?
之前在写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项目:
- Github: https://github.com/dyc87112/SpringCloud-Learning/tree/master/4-Finchley
- Gitee: https://gitee.com/didispace/SpringCloud-Learning/tree/master/4-Finchley
如果您对这些感兴趣,欢迎star、follow、收藏、转发给予支持!
RabbitMQ延迟消息的延迟极限是多少?的更多相关文章
- SpringCloud 2020.0.4 系列之 Stream 延迟消息 的实现
1. 概述 老话说的好:对待工作要有责任心,不仅要完成自己的部分,还要定期了解整体的进展. 言归正传,我们在开发产品时,常常会遇到一段时间后检查状态的场景,例如:用户下单场景,如果订单生成30分钟后, ...
- RabbitMQ延迟消息学习
准备做一个禁言自动解除的功能,立马想到了订单的超时自动解除,刚好最近在看RabbitMQ的实现,于是想用它实现,查询了相关文档发现确实可以实现,动手编写了这篇短文. 准备工作 1.Erlang安装请参 ...
- rabbitmq的延迟消息队列实现
第一部分:延迟消息的实现原理和知识点 使用RabbitMQ来实现延迟任务必须先了解RabbitMQ的两个概念:消息的TTL和死信Exchange,通过这两者的组合来实现上述需求. 消息的TTL(Tim ...
- Spring Boot RabbitMQ 延迟消息实现完整版
概述 曾经去网易面试的时候,面试官问了我一个问题,说 下完订单后,如果用户未支付,需要取消订单,可以怎么做 我当时的回答是,用定时任务扫描DB表即可.面试官不是很满意,提出: 用定时任务无法做到准实时 ...
- SpringBoot | 第三十八章:基于RabbitMQ实现消息延迟队列方案
前言 前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制.此机制,在原先对接银联支付时,银联的异步通知也是类似的,在第一次通知 ...
- Spring Cloud Stream 使用延迟消息实现定时任务(RabbitMQ)
应用场景 通常在应用开发中我们会碰到定时任务的需求,比如未付款订单,超过一定时间后,系统自动取消订单并释放占有物品. 许多同学的第一反应就是通过spring的schedule定时任务轮询数据库来实现, ...
- RabbitMQ延迟消息:死信队列 | 延迟插件 | 二合一用法+踩坑手记+最佳使用心得
前言 前段时间写过一篇: # RabbitMQ:消息丢失 | 消息重复 | 消息积压的原因+解决方案+网上学不到的使用心得 很多人加了我好友,说很喜欢这篇文章,也问了我一些问题. 因为最近工作比较忙, ...
- 基于redis的延迟消息队列设计
需求背景 用户下订单成功之后隔20分钟给用户发送上门服务通知短信 订单完成一个小时之后通知用户对上门服务进行评价 业务执行失败之后隔10分钟重试一次 类似的场景比较多 简单的处理方式就是使用定时任务 ...
- Spring Boot 实现 RabbitMQ 延迟消费和延迟重试队列
本文主要摘录自:详细介绍Spring Boot + RabbitMQ实现延迟队列 并增加了自己的一些理解,记录下来,以便日后查阅. 项目源码: spring-boot-rabbitmq-delay-q ...
随机推荐
- 《Windows via C/C++》学习笔记 —— 设备I/O之“同步的设备I/O”(系列文章)
前面曾经讲过,设备I/O的方式有两种:同步和异步.本篇介绍一下同步设备I/O.主要涉及到两个函数:ReadFile和WriteFile. 不要被这两个函数的名称迷惑,不仅可以将这两个作用于文件,也可以 ...
- 该内存不能read 或written数值 叙述(居然还有具体的讲究)
该内存不能read 或written数值 叙述 0 0x0000 作业完成. 1 0x0001 不正确的函数. 2 0x0002 系统找不到指定的档案. 3 0x0003 系统找不到指定的路径. 4 ...
- layui打印表格自定义函数
函数如下 function print (tablelayid) { var v = document.createElement("div"); var f = ["& ...
- DataVeryLite和Nhibernate性能对比
电脑型号:acer 4752g 电脑配置: 代码分享: class Program { static void Main(string[] args) { Debug.Listeners.Add(ne ...
- ORACLE(student)表习题与答案
因为答案都是小编自己写的,解法可能有多种,如果您觉得我的解法有误,希望您有时间给我留言. 题目:1. 查询student表中的所有记录的sname.ssex和class列. SELECT sname, ...
- selenium工作原理详解
selenium简介 Selenium是一个用于Web应用程序自动化测试工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11), ...
- Verilog写一个对数计算模块Log2(x)
网上一个能用的也没有,自己写一个把. 1.计算原理: 整数部分 网上找到了一个c语言的计算方法如下: int flog2(float x) { return ((unsigned&)x> ...
- Python自学day-11
一.RabbitMQ概述 RabbitMQ是一种消息队列,是一个公共的消息中间件,用于不同进程之间的通讯. 除了RabbitMQ以外,还有ZeroMQ.ActiveMQ等等. 前面学习了两种队列: 线 ...
- SCIgen与野鸡期刊的梗
layout: post title: "SCIgen与野鸡期刊的梗" date: 2019-04-28 19:06:21 +0800 --- 作者:吴甜甜 个人博客网站: wut ...
- C# Invoke
最近在看一个项目,其中用到异步进程——控件Invoke,这里将具体用法介绍如下: 以进度条为例: //声明委托 delegate void SetProgressBarEnabledDelegate( ...