RabbitMQ 延迟消息的极限是多少
银帆 2019-10-10 来源 : 阅读 3072 评论 0

摘要:本文主要向大家介绍了JAVA语言之消息队列 RabbitMQ 的延迟消费极限时间,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言之消息队列 RabbitMQ 的延迟消费极限时间,希望对大家学习JAVA语言有所帮助。


RabbitMQ 延迟消息的极限是多少

问题描述:

最近在使用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延迟消费未能按照想要的结果执行,问题在于有消费时间限制

问题结论

  1. 在明确问题之后,则需要对该队列做些明确的限制(延长时间的极限时间),以免再次发生同样的问题

  2. 深入了解之后,发现失败的主要原因与消息的过期时间(TTL)有直接关系

  3. 在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频道!

本文由 @银帆 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程