摘要:本文主要向大家介绍了JAVA语言之消息队列 RabbitMQ 的延迟消费极限时间,希望对大家学习JAVA语言有所帮助。
本文主要向大家介绍了JAVA语言之消息队列 RabbitMQ 的延迟消费极限时间,希望对大家学习JAVA语言有所帮助。
问题描述:
最近在使用RabbitMQ 死信队列时,发现有些队列成功实现延迟消费,有些队列被立即消费,通过查询相关文档终于解决问题,因此记录下来分享一下心得
问题定位;
因为不是所有的消息都出现了没有延迟消息效果的因素,通过有问题的消息特征,大致猜测可能是延迟时间过长导致了消息延迟失败.
编写测试代码
/** * 创建延时队列 * @param rabbitEnum * @param ttlEnum * @param msg */ public void sendToTopicTtlQueue(RabbitEnum rabbitEnum, RabbitTtlEnum ttlEnum, Object msg, final long dalayTimes){ // 创建实际消费队列 DirectExchange exchange = new DirectExchange(rabbitEnum.getExchange()); addExchange(exchange); // 消息中心实际消费队列配置 Queue queue = new Queue(rabbitEnum.getQueueName()); addQueue(queue); // 消息中心实际消息交换机与队列绑定 addBinding(queue, exchange, rabbitEnum.getRoutingKey()); // 创建消息中心延迟消费交换配置 exchange = new DirectExchange(ttlEnum.getExchange()); addExchange(exchange); Map params = new HashMap<>(2); // x-dead-letter-exchange 声明了队列里的死信转发到的DLX名称, params.put("x-dead-letter-exchange",rabbitEnum.getExchange()); // x-dead-letter-routing-key 声明了这些死信在转发时携带的 routing-key 名称。 params.put("x-dead-letter-routing-key",rabbitEnum.getRoutingKey()); queue = new Queue(ttlEnum.getName(), true, false, false, params); addQueue(queue); // 消息中心实际消息交换机与队列绑定 addBinding(queue, exchange, ttlEnum.getRouteKey()); rabbitTemplate.convertAndSend(ttlEnum.getExchange(), ttlEnum.getRouteKey(), msg,message -> { message.getMessageProperties().setExpiration(String.valueOf(dalayTimes)); return message; }); }
public static void main(String[] args) { RabbitUtil rabbitUtil=new RabbitUtil(); rabbitUtil.sendToTopicTtlQueue(RabbitEnum.MESSAGE_QUEUE,RabbitTtlEnum.MESSAGE_TTL_QUEUE, JSON.toJSONString(obj),1000*60*2); }
调用代码,第一个参数为消费队列,第二个参数为死信队列,第三个参数为JSON数据,第四个参数为延长时间 设置为2分钟
执行main() 实现两分钟之后消费
public static void main(String[] args) { RabbitUtil rabbitUtil=new RabbitUtil(); rabbitUtil.sendToTopicTtlQueue(RabbitEnum.MESSAGE_QUEUE,RabbitTtlEnum.MESSAGE_TTL_QUEUE, JSON.toJSONString(obj),1000*60*60*24*365); }
再次调用 ,延迟时间设置为1年,发现被立即消费,当前即可定位为RabbitMQ延迟消费未能按照想要的结果执行,问题在于有消费时间限制
问题结论
在明确问题之后,则需要对该队列做些明确的限制(延长时间的极限时间),以免再次发生同样的问题
深入了解之后,发现失败的主要原因与消息的过期时间(TTL)有直接关系
在RabbitMQ中,消息过期时间必须是非负32为整数,即:0<=n<=2^32-1,单位(毫秒) 。2^32-1=4294967295 约等于49天左右
下面进行实验:
public static void main(String[] args) { RabbitUtil rabbitUtil=new RabbitUtil(); rabbitUtil.sendToTopicTtlQueue(RabbitEnum.MESSAGE_QUEUE,RabbitTtlEnum.MESSAGE_TTL_QUEUE, JSON.toJSONString(obj),4294967296); rabbitUtil.sendToTopicTtlQueue(RabbitEnum.MESSAGE_QUEUE,RabbitTtlEnum.MESSAGE_TTL_QUEUE, JSON.toJSONString(obj),4294967295); }
分别生成两个延时队列,为4294967296跟4294967295,执行结果为第一个立即被消费,第二个延迟正常等待时间截止再进行消费
总结
RabbitMQ延迟消费极限时长为49天,若该时长不满足业务需求,则应该考虑不使用RabbitMQ作为延迟队列,使用其他的方法来实现定时或延迟任务。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号