|
|
|
|
公众号矩阵

6.2.2 死信队列消息模型实战(1)

《分布式中间件技术实战(Java版)》第6章RabbitMQ死信队列实战,本章主要有:死信队列/延迟队列的简介、作用以及典型应用场景介绍。理解并掌握RabbitMQ死信队列相关专有词汇和消息模型,并基于Spring Boot项目搭建死信队列消息模型,最终以代码实战消息的发送和接受。以实际的应用场景“商城平台订单支付超时”为案例,掌握如何用代码实战实现实际业务场景中死信队列模型的构建和消息的延迟发送接受。本节为死信队列消息模型实战。

作者:钟林森来源:机械工业出版社|2021-02-04 20:44

6.2.2  死信队列消息模型实战(1)
 
而死信队列,也是队列的一种,同样也是由基本的交换机和基本的路由“绑定”而成,只不过跟传统的普通队列相比,它拥有“延迟、延时处理消息”的功效,而之所以死信队列具有此种功能,主要还是得归结于它的“组成成分”,即死信队列主要由三个成员组成:DLX(死信交换机)、DLK(死信路由)和TTL(存活时间),其中死信交换机和死信路由是必需的组成成分,而TTL即存活时间是非必需的成分,图6.5为消息在死信队列所构成的消息模型中整体的传输流程。
 

从图6.5中可以看出,生产者生产的消息在死信队列构成的消息模型中整体的传输流程是这样的:首先消息将到达第一个中转站,即“基本消息模型”中的“基本交换机”,由于基本交换机和基本路由绑定对应到“死信队列”,故而消息将进入到第一个暂存区,即“死信队列”中,而死信队列不同于一般、普通的队列。

它由三大部分组成,包括死信交换机、死信路由和TTL存活时间,当消息进入死信队列时,TTL(即存活时间)便开始进入倒计时,当存活时间一到,消息将进入第二个中转站,即“真正消息模型”中的死信交换机,又由于死信交换机和死信路由绑定对应到“真正队列”,故而此时消息将不做停留,而是直接被路由到第二个暂存区,即“真正队列”中,最终该消息被真正队列对应的消费者监听消费,至此“消息”才完成了漫长的旅程!

对于RabbitMQ的死信队列,直白点理解,就是消息一旦进入死信队列,将会等待TTL的时间,而TTL一到,消息将会进入死信交换机,然后被路由到绑定的真正队列中,最终被真正队列对应的消费者监听消费!

值得一提的是,TTL既可以设置成为死信队列的一部分,也可以在消息中单独进行设置,当队列跟消息同时都设置了存活时间TTL时,则消息的“最大生存时间”或者“存活时间”将取两者中较短的时间。

在采用代码实战之前,笔者强烈建议各位读者有必要再认真的阅读图6.5的内容,即消息在死信队列构成的消息模型中传输的整体流程,其中,值得重点提醒的是几个“动词”的含义:

“绑定”:所谓绑定,其实就是采用BindingBuilder的bind()方法,将交换机和路由绑定在一起,对应到指定的队列,从而构成消息模型;

“组成”:顾名思义,是某个组件的一部分,比如死信队列的创建,它将由三大部分组成,包括DLX、DLK和TTL(当然也可以是两大部分,因为TTL非必需),在后面代码实战中,会发现其实它就是采用new Queue()方法中最后一个参数map来添加指定的成员,如图6.6所示。

 

 
“组成”跟“绑定”是两个完全不同的概念,在后续死信队列消息模型的代码实战中,各位读者将会慢慢体会这其中的“奥妙”!
 
接下来以前面章节搭建好的Spring Boot整合RabbitMQ的项目作为奠基,搭建RabbitMQ死信队列的消息模型,并在下一小节以实际的代码实战死信队列延迟发送消息的功能,其中,相关的代码文件所在的目录结构如图6.7所示。
 

(1)其中,DeadInfo实体类将充当“消息”,在这里,我们只给实体类创建两个字段,分别是id和描述信息(在这里并没有太多的含义),其源代码如下所示:

 
  1. //导入依赖包 
  2. import lombok.Data; 
  3. import lombok.ToString; 
  4. import java.io.Serializable; 
  5. /**死信队列实体对象信息 
  6.  * @Author:debug (SteadyJack) 
  7. **/ 
  8. @Data 
  9. @ToString 
  10. public class DeadInfo implements Serializable{ 
  11.     private Integer id; //标识id 
  12.     private String msg; //描述信息 
  13.     //空的构造方法 
  14.     public DeadInfo() { 
  15.     } 
  16.     //包含所有参数的构造方法 
  17.     public DeadInfo(Integer id, String msg) { 
  18.         this.id = id; 
  19.         this.msg = msg; 
  20.     } 
(2)在RabbitmqConfig配置类中创建包含死信队列的基本消息模型和包含真正队列的真正消息模型,其源代码如下所示:
 
 
  1. /**死信队列消息模型构建**/ 
  2. //创建死信队列 
  3. @Bean 
  4. public Queue basicDeadQueue() { 
  5.     //创建死信队列的组成成分map,用于存放组成成分的相关成员 
  6.     Map<String, Object> args = new HashMap(); 
  7.     //创建死信交换机 
  8.     args.put("x-dead-letter-exchange", env.getProperty("mq.dead.exchange.name")); 
  9.     //创建死信路由 
  10.     args.put("x-dead-letter-routing-key", env.getProperty("mq.dead.routing.key.name")); 
  11.     //设定TTL,单位为ms,在这里指的是10s 
  12.     args.put("x-message-ttl", 10000); 
  13.     //创建并返回死信队列实例 
  14.     return new Queue(env.getProperty("mq.dead.queue.name"), true, false, false, args); 
  15. //创建“基本消息模型”的基本交换机 - 面向生产者 
  16. @Bean 
  17. public TopicExchange basicProducerExchange() { 
  18.     //创建并返回基本交换机实例 
  19.     return new TopicExchange(env.getProperty("mq.producer.basic.exchange.name"), true, false); 
  20.  
  21. //创建“基本消息模型”的基本绑定-基本交换机+基本路由 - 面向生产者 
  22. @Bean 
  23. public Binding basicProducerBinding() { 
  24.     //创建并返回基本消息模型中的基本绑定 
  25.     return BindingBuilder.bind(basicDeadQueue()).to(basicProducerExchange()).with(env.getProperty("mq.producer.basic.routing.key.name")); 
  26. //创建真正队列 - 面向消费者 
  27. @Bean 
  28. public Queue realConsumerQueue() { 
  29.     //创建并返回面向消费者的真正队列实例 
  30.     return new Queue(env.getProperty("mq.consumer.real.queue.name"), true); 
  31. //创建死信交换机 
  32. @Bean 
  33. public TopicExchange basicDeadExchange() { 
  34.     //创建并返回死信交换机实例 
  35.     return new TopicExchange(env.getProperty("mq.dead.exchange.name"), true, false); 
  36. //创建死信路由及其绑定 
  37. @Bean 
  38. public Binding basicDeadBinding() { 
  39.     //创建死信路由及其绑定实例 
  40.     return BindingBuilder.bind(realConsumerQueue()).to(basicDeadExchange()).with(env.getProperty("mq.dead.routing.key.name")); 
 
 

喜欢的朋友可以加入官方的读书群

51CTO读书频道二维码


51CTO读书会第9群:808517103
【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

数据湖与数据仓库的分析实践攻略

数据湖与数据仓库的分析实践攻略

助力现代化数据管理:数据湖与数据仓库的分析实践攻略
共3章 | 创世达人

5人订阅学习

云原生架构实践

云原生架构实践

新技术引领移动互联网进入急速赛道
共3章 | KaliArch

31人订阅学习

数据中心和VPDN网络建设案例

数据中心和VPDN网络建设案例

漫画+案例
共20章 | 捷哥CCIE

216人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微