RabbitMQ - 死信、TTL原理、延迟队列安装和配置

2023-09-20 23:22:22

目录

一、死信交换机

1.1、什么是死信交换机

1.2、TTL

1.2.1、什么是 TTL 

1.2.2、通过 TTL 模拟触发死信

二、延迟队列

2.1、什么是延迟队列

2.2、配置延迟队列插件

2.2.1、延迟队列配置

a)下载镜像

b)运行容器

c)刚刚设定的RabbitMQ的数据卷名称为`mq-plugins`,所以我们使用下面命令查看数据卷:

d)在此目录下,进入 MQ 容器内部.

e)开启插件

2.3、SpringAMQP 使用延迟队列插件


一、死信交换机


1.1、什么是死信交换机

想要知道什么是死信交换机,先来看看什么是死信(dead letter)~

当生产者发送了一个消息,经过交换机到达队列时,满足下列情况之一时,就可以成为死信:

  • 消费者使用 basic.reject 或 basic.nack 声明消费失败,并且消息的 requeue 参数设置为 false(消息不重新加入到队列中).
  • 消息设置了过期时间,到了时间没有被消费掉.
  • 要投递的队列消息堆积满了(队列设置了最大消息数目),最早的消息可能会成为死信(LRU 算法淘汰的消息).

那么如果这个时候,一个队列配置了 dead-letter-exchange 属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机就称为 死信交换机.

1.2、TTL

1.2.1、什么是 TTL 

TTL 就是过期时间.  如果一个队列中的消息到了过期时间还没有被消费, 就会变成死信.

这里的消息到了过期时间实际上有两种情况:

  • 消息所在的队列设置了消息过期时间(x_message_ttl).
  • 消息本身设置了存活时间.

1.2.2、通过 TTL 模拟触发死信

a)声明一个直接交换机和一个配置了过期时间(x-message-ttl 属性)以及配 deadLetterExchange、deadLetterRoutingKey 属性的普通队列,用来生成死信

@Configuration
public class TTLMessageConfig {

    @Bean
    public DirectExchange ttlDirectExchange() {
        return new DirectExchange("ttl.direct");
    }

    @Bean
    public Queue ttlQueue() {
        return QueueBuilder
                .durable("ttl.queue")
                .ttl(5000)  //延时 5 s
                .deadLetterExchange("dl.direct") //消息如果超时没被消费就给这个死信交换机
                .deadLetterRoutingKey("dl")
                .build();
    }

    @Bean
    public Binding ttlBinding() {
        return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");
    }

}

b)这里我们基于注解的方式,声明一组死信交换机和队列

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "dl.queue", durable = "true"),
            exchange = @Exchange(name = "dl.exchange"),
            key = "dl"
    ))
    public void listenDlQueue(String msg) {
        log.info("消费者收到死信消息!msg=" + msg);
    }

c)生产者发送一个过期时间为 5s 的消息

    @Test
    public void testTTLMessage() {
        //1.构造一个消息
        Message message = MessageBuilder.withBody("hello ttl message".getBytes())
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setExpiration("5000")
                .build();
        //2.发送消息
        rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);
        //3.记录日志
        log.info("消息已经成功发送!");
    }

d)执行结果如下

Ps:通过执行结果,也可以看出,如果消息和队列都设置了过期时间,那么以时间短的为主.

二、延迟队列


2.1、什么是延迟队列

刚刚我们利用 TTL 结合死信交换机,实现了当消息发出后,消费者延迟收到消息的效果。这种消息模式就成为 延迟队列(Delay Queue) 模式。

延迟队列经常用于以下场景:

  1. 延迟发送短信.
  2. 用户下单,如果再 5 分钟内没有支付,就自动取消.
  3. 预约工作会议,10 分钟后自动通知所有参会人员.

2.2、配置延迟队列插件

由于 利用 TTL 结合死信交换机的方式实现起来比较麻烦,并且延迟队列的需求又非常多,因此 RabbitMQ 官方推出了一个插件,可以通过更简单的方式,达到延迟队列的效果.

2.2.1、延迟队列配置

我们在Centos7虚拟机中使用Docker来安装。

a)下载镜像
docker pull rabbitmq:3.8-management

b)运行容器
docker run \
 -e RABBITMQ_DEFAULT_USER=itcast \
 -e RABBITMQ_DEFAULT_PASS=123321 \
 -v mq-plugins:/plugins \
 --name mq \
 --hostname mq1 \
 -p 15672:15672 \
 -p 5672:5672 \
 -d \
 rabbitmq:3.8-management

Ps:此命令还额外配置了插件目录对应的数据卷.

c)刚刚设定的RabbitMQ的数据卷名称为`mq-plugins`,所以我们使用下面命令查看数据卷:
docker volume inspect mq-plugins

结果如下 

使用 cd 命令切换到 Mountpoint 指定的目录下.

d)在此目录下,进入 MQ 容器内部.

我的容器名为`mq`,所以执行下面命令:

docker exec -it mq bash

e)开启插件

进入容器内部后,执行以下命令开启插件:

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

2.3、SpringAMQP 使用延迟队列插件

a)声明一个延迟队列.  这里实际上和声明普通交换机只多出了一个 delayed 属性,设置为 true 就表示为延迟队列.

以下是基于 注解的方式声明交换机、队列、绑定.

Ps:如果是通过 java 代码的方式声明交换机,只需要 ExchangeBuilder().directExhange.delay() 即可.

@Component
@Slf4j
public class SpringRabbitListener {

    @RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "delay.queue", durable = "true"),
            exchange = @Exchange(name = "delay.direct", delayed = "true"),
            key = "delay"
    ))
    public void listenDelayExchange(String msg) {
        log.info("消费者接收到到了延迟消息!msg=" + msg);
    }

}

b)生产者只需要在生产消息的时候添加一个 header:"x-delay",对应的值就是延迟时间,单位是毫秒:

    @Test
    public void testDelayMessage() {
        //1.准备消息
        Message message = MessageBuilder.withBody("hello ttl message".getBytes())
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setHeader("x-delay", 5000) // 消息延迟时间
                .build();
        //2.消息 ID 需要封装到 CorrelationData 中
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        //3.发送消息
        rabbitTemplate.convertAndSend("delay.direct", "delay", message, correlationData);
        log.info("消息已经成功发送!");
    }

c)结果如下 

更多推荐

Linux 的性能调优的思路

Linux操作系统是一个开源产品,也是一个开源软件的实践和应用平台,在这个平台下有无数的开源软件支撑,我们常见的apache、tomcat、mysql等。开源软件的最大理念是自由、开放,那么Linux作为一个开源平台,最终要实现的是通过这些开源软件的支持,以最低廉的成本,达到应用最优的性能。因此,谈到性能问题,主要实现

OpenCV实战(30)——OpenCV与机器学习的碰撞

OpenCV实战(30)——OpenCV与机器学习的碰撞0.前言1.机器学习简介2.基于局部二值模式的最近邻人脸识别3.图像表示与人脸识别4.完整代码小结系列链接0.前言随着人工智能的发展,许多机器学习算法开始用于解决机器视觉问题。机器学习是一个广泛的研究领域,包含许多重要的概念,本节我们将介绍一些主要的机器学习技术,

ClickHouse进阶(二十):clickhouse管理与运维-熔断机制

进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容!🏡个人主页:IT贫道_大数据OLAP体系技术栈,ApacheDoris,Kerberos安全认证-CSDN博客📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情!👍点赞:赞同优秀创作,你的点赞是对我创作最大的认可!⭐️收藏:收藏原创

NuttX实时操作系统介绍(最详细)

比起安卓、iOS、鸿蒙等,NuttX知名度不算高,该系统于2007年由GregoryNutt先生正式开源。发展至今,NuttX以功能丰富、性能稳定、商业化成熟度高赢得了市场的认可。NuttX是一个成熟的实时操作系统,于07年由GregoryNutt先生正式开源,2016年被三星选为TizenRT操作系统的内核,2019

GNU-ncurses库简介

文章目录前言一、安装与使用二、ncurses库基本用法2.1initscr()2.2refresh()2.3endwin()三、初始化3.1raw(),cbreak()3.2echo()noecho()3.3keypad()3.4inthalfdelay(int)四、窗口机制简介五、输出函数六、输入函数七、输出修饰八、

Docker与Kubernetes集成以实现云原生应用程序:云原生在线教育平台

文章目录项目概述项目架构项目步骤项目收益🎈个人主页:程序员小侯🎐CSDN新晋作者🎉欢迎👍点赞✍评论⭐收藏✨收录专栏:云计算✨文章内容:云原生在线教育平台🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗当将Docker与Kubernetes集成以实现云原生应用程序时,可以采

Python开发利器之VS Code

Python官方提供了一个Python集成开发环境(IDE):IDLE(IntegratedDevelopmentandLearningEnvironment)。它提供了一个图形用户界面,可以让开发者编写、调试和执行Python程序。IDLE包含Python解释器、代码编辑器、调试器和文件浏览器等工具。IDLE非常适合

爬虫技术对携程网旅游景点和酒店信息的数据挖掘和分析应用

导语爬虫技术是一种通过网络爬取目标网站的数据并进行分析的技术,它可以用于各种领域,如电子商务、社交媒体、新闻、教育等。本文将介绍如何使用爬虫技术对携程网旅游景点和酒店信息进行数据挖掘和分析,以及如何利用Selenium库和代理IP技术实现爬虫程序。概述携程网是在线旅行服务平台,提供酒店预订、机票预订、旅游度假、商旅管理

学习笔记 --- RabbitMQ

简介RabbitMQ是一款开源的消息队列中间件,它实现了高级消息队列协议(AMQP)标准。作为一个消息代理,RabbitMQ可以在应用程序之间可靠地传递和存储消息,并支持多种消息传递模式。基本概念和特性消息:在RabbitMQ中,消息是传输的基本单位。它由消息体和可选的属性组成,消息体是要传递的实际数据,而属性则包含有

容器管理工具 Docker生态架构及部署

目录一、Docker生态架构1.1DockerContainersAreEverywhere1.2生态架构1.2.1DockerHost1.2.2Dockerdaemon1.2.3Registry1.2.4Dockerclient1.2.5Image1.2.6Container1.2.7DockerDashboard1

VL系列 Exchanging-based Multimodal Fusion with Transformer 论文阅读笔记

多模态融合Exchanging-basedMultimodalFusionwithTransformer论文阅读笔记一、Abstract二、引言三、相关工作3.1深度多模态融合四、方法4.1低维投影和embedding归一化低维投影Embedding归一化4.2多模态交换Transformer基础CrossTransf

热文推荐