RabbitMQ实践——对不可路由的消息的处理方法

大纲

  • 无备用(Alternate)交换器
    • 构建交换器、队列和绑定关系
    • 测试代码
      • 抛弃不可路由消息
      • 返还不可路由消息
  • 有备用(Alternate)交换器
    • 创建带备用(Alternate)交换器的交换器
    • mandatory
    • 非mandatory
  • 总结

在实际工作中,我们往往可能因为代码逻辑的一些问题导致发布的消息无法被路由,比如写错了Routing key。那么这个时候,RabbitMQ可能会拒绝接收,还可以通过其他机制把它收集起来。本文我们将探讨这类问题的处理方法。

无备用(Alternate)交换器

一般我们默认创建的交换器都是没有备用(Alternate)交换器的。

构建交换器、队列和绑定关系

我们给新建的交换器取名:direct.without.alternate。
在这里插入图片描述
然后创建一个名字叫direct_queue的队列
在这里插入图片描述
最后创建它们的绑定关系。Routing key是to.direct.queue。
在这里插入图片描述

测试代码

RabbitMQ的Client端和Server端通信时,是在一个连接(connection)上建立了一个双工通道(channel),即Client端可以给Server发消息,Server端也可以给Client端发消息。
当Client端向Server端发布一条消息后,Server端会根据Client端发送来的AMQP协议,决定是否要给告知Client端它对这条消息的处理结果。
如果Client设置了Mandatory为true,在消息没法被路由的情况下,Server端会通过告知Client端“NO_ROUTE”的处理结果,并将消息返还给Client端。如果消息被路由成功,则不会告知Client端。
在这里插入图片描述

private org.springframework.amqp.rabbit.core.RabbitTemplate createRabbitTemplate(org.springframework.amqp.rabbit.connection.ConnectionFactory connectionFactory, boolean mandatory) {org.springframework.amqp.rabbit.core.RabbitTemplate rabbitTemplate = null;if (connectionFactory instanceof CachingConnectionFactory cachingConnectionFactory) {cachingConnectionFactory.setPublisherReturns(true);rabbitTemplate = new org.springframework.amqp.rabbit.core.RabbitTemplate(cachingConnectionFactory);} else {throw new IllegalArgumentException("The provided connectionFactory is not an instance of CachingConnectionFactory");}rabbitTemplate.setMandatory(mandatory);rabbitTemplate.setReturnsCallback(returned -> {System.out.println(STR."Message returned: \{returned.getReplyText()} \n message: \{new String(returned.getMessage().getBody())} \n correlation id: \{returned.getMessage().getMessageProperties().getCorrelationId()} \n routing key: \{returned.getRoutingKey()} \n exchange: \{returned.getExchange()} \n reply code: \{returned.getReplyCode()}");});return rabbitTemplate;}

上述代码中setReturnsCallback方法设置了一个回调函数。当mandatory被设置为true,且消息无法被路由时,这个回调会被调用。
需要注意的是:发布消息和回调是发生在不同的过程中,它们是异步的关系。

抛弃不可路由消息

我们只要给Mandatory设置为false,则表示RabbitMQ可以接收不可路由消息,但是会将其抛弃。

@Bean(name = "rabbitTemplateWithoutMandatory")
public org.springframework.amqp.rabbit.core.RabbitTemplate rabbitTemplateWithoutMandatory(org.springframework.amqp.rabbit.connection.ConnectionFactory connectionFactory) {return createRabbitTemplate(connectionFactory, false);
}
@Service
public class NonmandatoryService {@Resource(name = "rabbitTemplateWithoutMandatory")private RabbitTemplate rabbitTemplateWithoutMandatory;public void send(String exchangeName, String routingKey, String message) {String msgId = UUID.randomUUID().toString();Message msg = MessageBuilder.withBody(message.getBytes()).setContentType("text/plain").setCorrelationId(msgId).setMessageId(msgId).build();CorrelationData correlationData = new CorrelationData(msgId);rabbitTemplateWithoutMandatory.convertAndSend(exchangeName, routingKey, msg, correlationData);}}

在这里插入图片描述

发送完消息后,队列中是看不到这条消息的。而且上述回调也没执行。
在这里插入图片描述
在这里插入图片描述

返还不可路由消息

当我们设置了Mandatory为true时,在“不可路由”的场景下,回调会被调用。

@Bean(name = "rabbitTemplateWithMandatory")
public org.springframework.amqp.rabbit.core.RabbitTemplate rabbitTemplateWithMandatory(org.springframework.amqp.rabbit.connection.ConnectionFactory connectionFactory) {return createRabbitTemplate(connectionFactory, true);
}
@Service
public class MandatoryService {@Resource(name = "rabbitTemplateWithMandatory")private RabbitTemplate rabbitTemplateWithMandatory;public void send(String exchangeName, String routingKey, String message) {String msgId = UUID.randomUUID().toString();Message msg = MessageBuilder.withBody(message.getBytes()).setContentType("text/plain").setCorrelationId(msgId).setMessageId(msgId).build();CorrelationData correlationData = new CorrelationData(msgId);rabbitTemplateWithMandatory.convertAndSend(exchangeName, routingKey, msg, correlationData);}
}

在这里插入图片描述

发送完消息后,队列中是看不到这条消息的。
在这里插入图片描述
但是上述回调函数会被执行。“不可路由”的错误码是312。
在这里插入图片描述

在这里插入图片描述

有备用(Alternate)交换器

在实际应用中,抛弃掉不可路由信息会让我们忽视掉没有注意到的意外情况,从而影响系统的正确性。但是如果我们开启mandatory功能,则会要求Client端来处理这些意外情况,导致业务系统复杂度增加。
一种比较优雅的解决方案是使用备用交换器,将这些意外信息存储到其他队列中,稍后再做分析和处理。
那备用交换器选用什么类型的呢?在《RabbitMQ实践——交换器(Exchange)和绑定(Banding)》中,我们介绍了各个交换器的特点。但是发现只有fanout类型交换器可以无条件路由消息,其他都要做匹配工作。所以fanout交换器是适合做备用交换器的。

创建带备用(Alternate)交换器的交换器

我们使用在《RabbitMQ实践——交换器(Exchange)和绑定(Banding)》中介绍的系统自建的amq.fanout作为备用交换器。
在这里插入图片描述
也构建和之前的绑定关系
在这里插入图片描述

然后给这个交换器发布消息。

mandatory

在这里插入图片描述
即使开启了mandatory模式,由于备用交换器的存在,RabbitMQ会将消息路由到备用交换器,而不会返还给Client端,于是回调代码不会被执行。
消息也会被备用交换器路由到它绑定的队列上。
在这里插入图片描述

非mandatory

在这里插入图片描述
由于存在备用交换器,非mandatory的消息也不会被RabbitMQ抛弃,而是会路由到备用交换器对应的队列中。
在这里插入图片描述

总结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/29293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【DevOps】Elasticsearch 数据跨集群同步方案

目录 1、Elasticsearch Cross-Cluster Replication (CCR) 1.1、优点 1.2、缺点 1.3、步骤 1.4、示例 2. Logstash 或其他 ETL 工具 2.1、优点 2.2、缺点 2.3、步骤 3. Apache Kafka 或 RabbitMQ 3.1、优点 3.2、缺点 3.3、步骤 4、使用 Reindex API 进行跨集群同…

【LeetCode最详尽解答】42-接雨水 Trapping-Rain-Water

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家! 链接: 42-接雨水 直觉 通过可视化图形来解决这个问题会更容易理解和解决。 给定输入: height [0,1,…

mediasoup源码分析--channel创建及信令交互

mediasoup源码分析--channel创建及信令交互 概述跨职能图业务流程图代码剖析 概述 在golang实现mediasoup的tcp服务及channel通道一文中,已经介绍过信令服务中tcp和channel的创建,本文主要讲解c中mediasoup的channel创建,以及信令服务和medi…

基于CentOS的全新Linux机器安装Jenkins并生成Allure报告

目录 一、安装Docker 二、安装Docker Compose 三、准备测试用例 四、配置docker-compose.yml 五、启动Jenkins 六、配置Jenkins和Allure插件 七、创建含pytest的Jenkins任务 一、安装Docker 在CentOS上,首先更新包管理工具并安装所需的包。 sudo yum update…

12.3 Go 测试覆盖率

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

基于Elementui组件,在vue中实现多种省市区前端静态JSON数据展示并支持与后端交互功能,提供后端名称label和id

基于Elementui组件,在vue中实现多种省市区前端静态数据(本地JSON数据)展示并支持与后端交互功能,提供后端名称label和id 话不多说,先上图 1.支持传递给后端选中省市区的id和名称,示例非常完整&#xff0c…

阿里云 邮件系统DNS域名解析 搭配 postfix+dovecot 邮件服务器

1 创建邮箱域名A记录(一般邮箱客户端,增加pop,imap,stmp 3条记录) 登录阿里云控制台--云解析DNS 2 MX记录 3 SPF记录

【论文复现|智能算法改进】基于多策略的改进蜜獾算法及其应用

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】蜜獾算法(HBA)原理及实现 2.改进点 限制反向学习机制 在挖掘模式和蜂蜜模式不同路径更新的基础上引入限制反向学习机制,在算法迭代时,对当前的…

Fegin如何传参form-data文件

Form-data传输file参数,这个大家都比较清楚,那么针对于Fegin参数file参数该如何操作呢!下面截图来找到对应的参数关系。 一、之前我们在postMan中是这种传参的,那么如果使用Feigin来传输文件File 二、在Fegin中传form-data参数&a…

C/C++ struct stat介绍

目录 前言 struct stat struct stat 使用 参考 共勉 前言 本文详细介绍了stat结构体的成员变量,以及使用案例,希望能够帮到您。 struct stat struct stat 结构体用于表示文件或者文件系统对象信息的一种结构体的声明,通常在POSIX&#x…

Mac M3 Pro 部署Flink-1.16.3

目录 1、下载安装包 2、解压及配置 3、启动&测试 4、测试FlinkSQL读取hive数据 以上是mac硬件配置 1、下载安装包 官网:Downloads | Apache Flink 网盘: Flink 安装包 https://pan.baidu.com/s/1IN62_T5JUrnYUycYMwsQqQ?pwdgk4e Flink 已…

【ComfyUI】Stable Diffusion 3 加Controlnet

基于 instantX-research/diffusers_sd3_control: 🤗 Diffusers: State-of-the-art diffusion models for image and audio generation in PyTorch and FLAX. (github.com) 和 ZHO-ZHO-ZHO/ComfyUI-SD3-Medium-CN-Diffusers: ComfyUI SD3-Medium ControlNet&#…

html入门综合练习

综合练习 通过实际项目练习可以更好地理解和掌握HTML、CSS和JavaScript。以下是几个综合练习项目的建议: 项目1:个人简历网页 创建一个包含以下内容的个人简历网页: 个人简介(姓名、照片、联系方式)教育背景工作经…

Survival Animations

一套生存游戏的动画集,包括采集、建造、捕鱼、剥皮/鞣制、篝火等更多内容。 总动画数:89 建造/制作 30 篝火 28 饮水 3 水壶 3 觅食 2 治疗 3 空闲 1 原始捕鱼 7 剥皮 1 矛捕鱼 4 伐木 5 下载:​​Unity资源商店链接资源下载链接 效果图:

[自动驾驶 SoC]-4 特斯拉FSD

FSD, 参考资料来源FSD Chip - Tesla - WikiChip 另外可参考笔者之前分享文章:[自动驾驶技术]-6 Tesla自动驾驶方案之硬件(AI Day 2021),​​​​​​​[自动驾驶技术]-8 Tesla自动驾驶方案之硬件(AI Day 2022&#xf…

Java多线程下载工具,多线程,多任务,断点续传,GUI

目录 一、题目要求 二、效果展示 三、功能实现 四、代码 一、题目要求 序号 功能名称 功能需求标识 简要描述 1 下载功能 Download 当用户输入一个下载链接后,能识别链接并开始多线程下载工作,包括线程监听、线程管理等。 2 续传功能 …

MMpose安装实例

摘要: 这个大数据训练发展较快,各种版本问题,不太好匹配,仅是安装就会大费周章。本文图文并茂的描述了一种成功的安装方式。仅供参考。 使用的win版本是win11,英伟达显卡是GeForce GTX 1660 SUPER。 1.cuda版本选择 通…

浏览器f12控制台怎么获取vue实例,并且修改data数据

我们在日常的生产工作中,经常会遇到一些问题,比如,若产品已经部署,或是目前无法查看源代码,或者向用命令直接修改查询默认表单数据,那我们怎么去查看Vue实例呢? 我们在浏览器直接打印this不能得…

基于JSP技术的弹幕视频网站系统

开头语 你好,你好呀,我是计算机学长猫哥!如果有相关需求,可以通过文末的联系方式找到我。 开发语言 JSP 数据库 MySQL 技术 JSP JavaBeans 工具 MyEclipse、Tomcat、Navicat 系统展示 首页 用户登录界面 视频信息界面…

《跟我一起学“网络安全”》——等保风评加固应急响应

等保风评加固应急响应 一、安全加固 背景 随着IP技术的飞速发展,一个组织的信息系统经常会面临内部和外部威胁的风险,网络安全已经成为影响信息系统的关键问题。 虽然传统的防火墙等各类安全产品能提供外围的安全防护,但并不能真正彻底的消…