Docker 下 RabbitMQ 延时队列实战两部曲之二:细说开发
欢迎访问我的 GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本章是《Docker 下 RabbitMQ 延时队列实战两部曲》的终篇,上一章《Docker下RabbitMQ延时队列实战两部曲之一:极速体验》我们快速体验了延时队列的生产和消费,今天来实战整个开发过程;
本章涉及的脚本和源码下载
本章会开发一个 yml 脚本,三个基于 SpringBoot 的应用,功能如下:
docker-compose.yml:启动所有容器的 docker-compose 脚本;
delayrabbitmqconsumer:SpringBoot 框架的应用,连接 RabbitMQ 的两个队列,消费消息;
messagettlproducer:SpringBoot 框架的应用,收到 web 请求后向 RabbitMQ 发送消息,消息中带有过期时间(TTL);
queuettlproducer:SpringBoot 框架的应用,收到 web 请求后向 RabbitMQ 发送消息,消息中不带过期时间(TTL),但是对应的消息队列已经设置了过期时间;
整体部署情况如下:
上述脚本和工程的源码都可以在 github 下载,地址和链接信息如下表所示:
这个 git 项目中有多个文件夹,三个 SpringBoot 工程分别在 delayrabbitmqconsumer、messagettlproducer、queuettlproducer 这三个文件夹下,如下图的三个红框所示:
docker-compose.yml 文件在 rabbitmq_docker_files 文件夹下面的 delaymq 文件夹下,如下图:
环境信息
操作系统:Ubuntu 16.04.3 LTS
Docker:1.12.6
RabbitMQ:3.7.5-rc.1
JDK:1.8.0_111
SpringBoot:1.4.1.RELEASE
Maven:3.5.0
开发步骤
本次开发实战的步骤如下:
开发 messagettlproducer 应用,制作镜像;
开发 queuettlproducer 应用,制作镜像;
开发 delayrabbitmqconsumer 应用,制作镜像;
开发 docker-compose.yml 脚本;
messagettlproducer 应用
messagettlproducer 是个基于 SpringBoot 的 web 工程,有一个 Controller 可以响应 web 请求,收到请求后发送一条带有过期时间的消息到 RabbitMQ 的 message.ttl.queue.source 队列;
pom.xml 内容如下:
上面的内容中有以下两点需要注意:a. 添加对 spring-boot-starter-amqp 的依赖,这里面是操作 RabbitMQ 所需的库;b. 添加 docker-maven-plugin 插件,可以将当前工程直接制作成 Docker 镜像;
src/main/resources 文件夹下面创建 application.properties 文件,内容如下,只配置了应用名称和 RabbitMQ 的 virtualHost 路径:
RabbitTemplateConfig.java 文件中是应用连接 RabbitMQ 的配置信息:
上面的代码有以下几点要注意:a. address、username、password 这些变量的值,是从操作系统的环境变量中获取的,我们在启动 Docker 容器的时候将这些值配置到容器的环境变量中,程序运行的时候就能取到了;b. connectionFactory()方法根据上述配置参数和 RabbitMQ 建立连接;c. rabbitTemplate()创建 RabbitTemplate 对象,我们可以在其他 Bean 中通过 Autowire 使用;
MessageTtlRabbitConfig.java 类中是和消息队列相关的配置:
上面的代码有以下几点要注意:a. MESSAGE_TTL_EXCHANGE_NAME、MESSAGE_TTL_QUEUE_SOURCE、MESSAGE_TTL_QUEUE_PROCESS 这些变量的值,是从操作系统的环境变量中获取的,我们在启动 Docker 容器的时候将这些值配置到容器的环境变量中,程序运行的时候就能取到了;b. connectionFactory()方法根据上述配置参数和 RabbitMQ 建立连接;c. rabbitTemplate()创建 RabbitTemplate 对象,我们可以在其他 Bean 中通过 Autowire 使用;d. messageTtlQueueSource()方法创建了一个队列用于投递消息,通过 x-dead-letter-exchange 和 x-dead-letter-routing-key 这两个参数,设置了队列消息过期后转发的交换机名称,以及携带的 routing key;
为了设置消息过期,我们还要定制一个 ExpirationMessagePostProcessor 类,作用是将给消息类设置过期时间,后面发送消息时会用到这个类:
用于处理 web 请求的 SendMessageController 类,源码如下:
如上所示,发送消息的代码很简单,调用 rabbitTemplate 的 convertAndSend 就能发送消息到 message.ttl.queue.source 队列(指定路由键的 Direct 方式),再传入 ExpirationMessagePostProcessor 作为处理消息的工具;
以上就是 messagettlproducer 应用的主要代码介绍,编码完毕后,在 pom.xml 文件所在目录执行 mvn clean package -U -DskipTests docker:build,即可编译、构建、制作 Docker 镜像;
queuettlproducer 应用
queuettlproducer 和 messagettlproducer 极为相似,都是接受 web 请求后向 RabbitMQ 发送消息,不同之处有以下两点:
queuettlproducer 在绑定队列的时候,会设置队列上所有消息的过期时间,messagettlproducer 没做这个设置;
queuettlproducer 在发送消息的时候,没有设置该消息的过期时间,messagettlproducer 会对每条消息都设置过期时间;
因此,queuettlproducer 和 messagettlproducer 这两个应用的代码大部分是相同的,这里只要关注不同的部分即可;
队列和交换机的配置类,QueueTtlRabbitConfig:
上述代码请注意以下两点:a. queueTtlQueueSource()方法用来设置队列,除了 x-dead-letter-exchange 和 x-dead-letter-routing-key 这两个参数,还多了 x-message-ttl,此参数对应的值就是进入该队列的每一条消息的过期时间;b. bindingExchangeMessage()方法将队列 queue.ttl.queue.source 绑定到 Direct 模式的交换机;
处理 web 请求的 SendMessageController 类:
如上所示,发送消息时只有 routing key 和消息对象这两个参数;
以上就是发送消息到队列的应用源码,编码完毕后,在 pom.xml 文件所在目录执行 mvn clean package -U -DskipTests docker:build,即可编译、构建、制作 Docker 镜像;
接下来我们看看消息消费者工程 delayrabbitmqconsumer 的源码;
delayrabbitmqconsumer 应用
delayrabbitmqconsumer 应用连接到消息队列,消费收到的每条消息;
RabbitTemplateConfig.java 是连接到 RabbitMQ 的配置信息,和前面两个应用一样,不再赘述;
消费 message.ttl.queue.process 这个队列发出的消息,对应实现类是 MessageTtlReceiver:
如上所示,只要用注解 RabbitListener 配置好队列的名称即可,编码完毕后,在 pom.xml 文件所在目录执行 mvn clean package -U -DskipTests docker:build,即可编译、构建、制作 Docker 镜像;
docker-compose.yml 配置
最后我们看一下所有容器的配置文件 docker-compose.yml:
上述配置文件有以下几点需要注意:
rabbit1、rabbit2、rabbit3 是 RabbitMQ 高可用集群,如果您对 RabbitMQ 高可用集群感兴趣,推荐您请看《Docker下RabbitMQ四部曲》系列文章;
三个 SpringBoot 应用都配置了 mq.rabbit.address 参数,值是三个 RabbitMQ server 的 IP 加端口,这样如果 RabbitMQ 集群中有一台机器故障了也不会影响正常的消息收发;
使用了 link 参数后,容器内就能通过 link 的参数取代对应的 IP;
至此,Docker 下的 RabbitMQ 延时队列实战就完成了,实战中 Docker 发挥的作用并不大,只是用来快速搭建环境,关键还是三个工程中对队列的各种操作,希望本系列能帮助您快速构建延时队列相关服务;
欢迎关注 InfoQ:程序员欣宸
版权声明: 本文为 InfoQ 作者【程序员欣宸】的原创文章。
原文链接:【http://xie.infoq.cn/article/50307d9ccf7c5a3f9eba6cb7f】。文章转载请联系作者。
评论