基于队列和基于消息的TTL

TTL是time to live 的简称,顾名思义指的是消息的存活时间。rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身。

队列消息过期时间-Per-Queue Message TTL:

通过设置队列的x-message-ttl参数来设置指定队列上消息的存活时间,其值是一个非负整数,单位为微秒。不同队列的过期时间互相之间没有影响,即使是对于同一条消息。队列中的消息存在队列中的时间超过过期时间则成为死信。

死信交换机DLX

队列中的消息在以下三种情况下会变成死信

(1)消息被拒绝(basic.reject 或者 basic.nack),并且requeue=false;

(2)消息的过期时间到期了;

(3)队列长度限制超过了。

当队列中的消息成为死信以后,如果队列设置了DLX那么消息会被发送到DLX。通过x-dead-letter-exchange设置DLX,通过这个x-dead-letter-routing-key设置消息发送到DLX所用的routing-key,如果不设置默认使用消息本身的routing-key.

  1. @Bean
  2. public Queue lindQueue() {
  3. return QueueBuilder.durable(LIND_QUEUE)
  4. .withArgument("x-dead-letter-exchange", LIND_DL_EXCHANGE)//设置死信交换机
  5. .withArgument("x-message-ttl", makeCallExpire)
  6. .withArgument("x-dead-letter-routing-key", LIND_DEAD_QUEUE)//设置死信routingKey
  7. .build();
  8. }

实现的过程

graph TD
publisher-->正常queue
正常queue-->TTL
TTL-->dead.queue
dead.queue-->subscriber

完整的代码

  1. @Component
  2. public class AmqpConfig {
  3. /**
  4. * 主要测试一个死信队列,功能主要实现延时消费,原理是先把消息发到正常队列,
  5. * 正常队列有超时时间,当达到时间后自动发到死信队列,然后由消费者去消费死信队列里的消息.
  6. */
  7. public static final String LIND_EXCHANGE = "lind.exchange";
  8. public static final String LIND_DL_EXCHANGE = "lind.dl.exchange";
  9. public static final String LIND_QUEUE = "lind.queue";
  10. public static final String LIND_DEAD_QUEUE = "lind.queue.dead";
  11. public static final String LIND_FANOUT_EXCHANGE = "lindFanoutExchange";
  12. /**
  13. * 单位为微秒.
  14. */
  15. @Value("${tq.makecall.expire:60000}")
  16. private long makeCallExpire;
  17. /**
  18. * 创建普通交换机.
  19. */
  20. @Bean
  21. public TopicExchange lindExchange() {
  22. return (TopicExchange) ExchangeBuilder.topicExchange(LIND_EXCHANGE).durable(true)
  23. .build();
  24. }
  25. /**
  26. * 创建死信交换机.
  27. */
  28. @Bean
  29. public TopicExchange lindExchangeDl() {
  30. return (TopicExchange) ExchangeBuilder.topicExchange(LIND_DL_EXCHANGE).durable(true)
  31. .build();
  32. }
  33. /**
  34. * 创建普通队列.
  35. */
  36. @Bean
  37. public Queue lindQueue() {
  38. return QueueBuilder.durable(LIND_QUEUE)
  39. .withArgument("x-dead-letter-exchange", LIND_DL_EXCHANGE)//设置死信交换机
  40. .withArgument("x-message-ttl", makeCallExpire)
  41. .withArgument("x-dead-letter-routing-key", LIND_DEAD_QUEUE)//设置死信routingKey
  42. .build();
  43. }
  44. /**
  45. * 创建死信队列.
  46. */
  47. @Bean
  48. public Queue lindDelayQueue() {
  49. return QueueBuilder.durable(LIND_DEAD_QUEUE).build();
  50. }
  51. /**
  52. * 绑定死信队列.
  53. */
  54. @Bean
  55. public Binding bindDeadBuilders() {
  56. return BindingBuilder.bind(lindDelayQueue())
  57. .to(lindExchangeDl())
  58. .with(LIND_DEAD_QUEUE);
  59. }
  60. /**
  61. * 绑定普通队列.
  62. *
  63. * @return
  64. */
  65. @Bean
  66. public Binding bindBuilders() {
  67. return BindingBuilder.bind(lindQueue())
  68. .to(lindExchange())
  69. .with(LIND_QUEUE);
  70. }
  71. /**
  72. * 广播交换机.
  73. *
  74. * @return
  75. */
  76. @Bean
  77. public FanoutExchange fanoutExchange() {
  78. return new FanoutExchange(LIND_FANOUT_EXCHANGE);
  79. }
  80. }
  81. //-----------------
  82. @Component
  83. public class Publisher {
  84. @Autowired
  85. private RabbitTemplate rabbitTemplate;
  86. public void publish(String message) {
  87. try {
  88. rabbitTemplate
  89. .convertAndSend(AmqpConfig.LIND_EXCHANGE, AmqpConfig.LIND_DELAY_QUEUE,
  90. message);
  91. } catch (Exception e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. }
  96. //-----------------
  97. @Component
  98. @Slf4j
  99. public class Subscriber {
  100. @RabbitListener(queues = AmqpConfig.LIND_QUEUE)
  101. public void customerSign(String data) {
  102. try {
  103. log.info("从队列拿到数据 :{}", data);
  104. } catch (Exception ex) {
  105. e.printStackTrace();
  106. }
  107. }
  108. }

rabbitmq实现延时队列(死信队列)的更多相关文章

  1. 《RabbitMQ》什么是死信队列

    一 什么是死信队列 当一条消息在队列中出现以下三种情况的时候,该消息就会变成一条死信. 消息被拒绝(basic.reject / basic.nack),并且requeue = false 消息TTL ...

  2. RabbitMQ延迟消息:死信队列 | 延迟插件 | 二合一用法+踩坑手记+最佳使用心得

    前言 前段时间写过一篇: # RabbitMQ:消息丢失 | 消息重复 | 消息积压的原因+解决方案+网上学不到的使用心得 很多人加了我好友,说很喜欢这篇文章,也问了我一些问题. 因为最近工作比较忙, ...

  3. 【RabbitMQ】一文带你搞定RabbitMQ死信队列

    本文口味:爆炒鱿鱼   预计阅读:15分钟 一.说明 RabbitMQ是流行的开源消息队列系统,使用erlang语言开发,由于其社区活跃度高,维护更新较快,性能稳定,深得很多企业的欢心(当然,也包括我 ...

  4. RabbitMQ使用 prefetch_count优化队列的消费,使用死信队列和延迟队列实现消息的定时重试,golang版本

    RabbitMQ 的优化 channel prefetch Count 死信队列 什么是死信队列 使用场景 代码实现 延迟队列 什么是延迟队列 使用场景 实现延迟队列的方式 Queue TTL Mes ...

  5. RabbitMQ与.net core(四) 消息的优先级 与 死信队列

    1.消息的优先级 假如现在有个需求,我们需要让一些优先级最高的通知推送到客户端,我们可以使用redis的sortedset,也可以使用我们今天要说的rabbit的消息优先级属性 Producer代码 ...

  6. RabbitMQ 消费端限流、TTL、死信队列

    目录 消费端限流 1. 为什么要对消费端限流 2.限流的 api 讲解 3.如何对消费端进行限流 TTL 1.消息的 TTL 2.队列的 TTL 死信队列 实现死信队列步骤 总结 消费端限流 1. 为 ...

  7. RabbitMQ TTL、死信队列

    TTL概念 TTL是Time To Live的缩写,也就是生存时间. RabbitMQ支持消息的过期时间,在消息发送时可以进行指定. RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过 ...

  8. 【MQ中间件】RabbitMQ -- RabbitMQ死信队列及内存监控(4)

    1.RabbitMQ TTL及死信队列 1.1.TTL概述 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取:过了之后消息将自动被删除.RabbitMQ可以对消息和队列设 ...

  9. RabbitMQ之死信队列

    1:何为死信队列 死信队列也是一个正常的队列,可以被消费. 但是,死信队列的消息来源于其他队列的转发. 2:如何触发死信队列 1:消息超时 2:队列长度达到极限 3:消息被拒绝消费,并不再重进队列,且 ...

  10. Spring Boot系列——死信队列

    在说死信队列之前,我们先介绍下为什么需要用死信队列. 如果想直接了解死信对接,直接跳入下文的"死信队列"部分即可. ack机制和requeue-rejected属性 我们还是基于上 ...

随机推荐

  1. Dubbo中SPI扩展机制解析

    dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...

  2. 【BZOJ 2844】: albus就是要第一个出场

    题目大意: 给一个长度为n的序列,将其子集的异或值排序得到B数组,给定一个数字Q,保证Q在B中出现过,询问Q在B中第一次出现的下标. 题解: 感觉和hdu3949第K小异或值有一像,然而发现要求出现次 ...

  3. Feature Preprocessing on Kaggle

    刚入手data science, 想着自己玩一玩kaggle,玩了新手Titanic和House Price的 项目, 觉得基本的baseline还是可以写出来,但是具体到一些细节,以至于到能拿到的出 ...

  4. openoffice转换pdf 异常问题查找处理 errorCode 525

    could not save output document; OOo errorCode: 525 该问题是由于java程序和openoffice的启动所属用户不同导致.使用以下命令查看端口和进程 ...

  5. monkey----log分析要求

    对monkey测试过程中生成的XXX.log文件中进行关键字的查找.主要查找讯息如下: (1) anr项:即无响应,一般形式为ANR in org.codeaurora.bluetooth: (2)c ...

  6. MySQL - 高可用性:少宕机即高可用?

    我们之前了解了复制.扩展性,接下来就让我们来了解可用性.归根到底,高可用性就意味着 "更少的宕机时间". 老规矩,讨论一个名词,首先要给它下个定义,那么什么是可用性? 1 什么是可 ...

  7. .NET Core + Ocelot + IdentityServer4 + Consul 基础架构实现

    先决条件 关于 Ocelot 针对使用 .NET 开发微服务架构或者面向服务架构提供一个统一访问系统的组件. 参考 本文将使用 Ocelot 构建统一入口的 Gateway. 关于 IdentityS ...

  8. 【Android Studio安装部署系列】目录

    概述 从刚开始使用Android Studio到现在,下面所有目录下的操作,当时习惯性的把每一个整理成一个文档(其实就是简单文字描述+截图):有些地方当时是一知半解,现在会稍微明白一些.正好赶上现在有 ...

  9. Redis客户端——Jedis的使用

    本文介绍基于Java语言的Redis客户端——Jedis的使用,包括Jedis简介.获取Jedis.Jedis直连.Jedis连接池以及二者的对比的选择. Jedis简介 Jedis 是 Redis  ...

  10. MVC图片上传详解

    MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFileBase shangch ...