千家信息网

RabbitMQ是怎么确定消息是否投递到队列中的

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,本篇内容介绍了"RabbitMQ是怎么确定消息是否投递到队列中的"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够
千家信息网最后更新 2025年01月17日RabbitMQ是怎么确定消息是否投递到队列中的

本篇内容介绍了"RabbitMQ是怎么确定消息是否投递到队列中的"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1. 前言

在使用RabbitMQ消息中间件时,因为消息的投递是异步的,默认情况下,RabbitMQ会删除那些无法路由的消息。为了能够检出消息是否顺利投递到队列,我们需要相应的处理机制。今天就来验证一下相关的验证机制。

2. 消息投递失败

那么哪些情况消息会投递失败呢?RabbitMQ消息会先到达指定的交换机,然后由交换机路由到对应的队列。所以以下几种情况会导致消息投递失败。

  • 投递的交换机不可用。

  • 投递的交换机可用,但是没有匹配到队列。

3. 投递失败的处理机制

对应上面的两种情况,RabbitMQ提供了对应的解决方案。

ConfirmCallback

RabbitMQ提供了ConfirmCallback接口用于实现消息发送到RabbitMQ交换器后进行确认回调。

在Spring Boot中需要开启:

spring:   rabbitmq:   # 通常选择 correlated     publisher-confirm-type:

通常有三种选择:

  • NONE ,禁用发布确认模式,是默认值。

  • CORRELATED,发布消息时会携带一个CorrelationData,被ack/nack时CorrelationData会被返回进行对照处理,CorrelationData可以包含比较丰富的元信息进行回调逻辑的处理。

  • SIMPLE,当被ack/nack后会等待所有消息被发布,如果超时会触发异常,甚至关闭连接通道。

这里我使用CORRELATED模式,声明一个ConfirmCallback并设置到RabbitTemplate中

rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {     // correlationData 可能为空     if (ack) {         log.debug("消息发送到exchange成功,id: {}", correlationData.getId());     } else {         log.debug("消息发送到exchange失败,原因: {}", cause);     } });

当消息投递到一个不存在的交换机Exchange且ack=false时会输出日志:

- Publishing message [(Body:'"hello"' MessageProperties [headers={spring_listener_return_correlation=a088eb3f-a234-4e15-bb7a-3aa9a6f043e6, spring_returned_message_correlation=29975bc1-f363-4e3a-85ca-010d13888720, __TypeId__=java.lang.String}, contentType=application/json, contentEncoding=UTF-8, contentLength=7, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])] on exchange [DIRECT_EXCHANGE1], routingKey = [DIRECT_ROUTING_KEY2]  - 消息发送到exchange失败,原因: channel error; protocol method: #method(reply-code=404, reply-text=NOT_FOUND - no exchange 'DIRECT_EXCHANGE1' in vhost 'my_vhost', class-id=60, method-id=40)

这里实现的比较简单你可以增加一些消息投递到交换机失败后的操作处理逻辑。

ReturnCallback

ReturnCallback接口用于实现消息已经成功发送到RabbitMQ交换机,但没有匹配到队列时的回调。

在Spring Boot中需要同时开启:

spring:   rabbitmq:     publisher-returns: true     template:       mandatory: true

RabbitTemplate中的mandatory设置值优先级要高一些。

我们声明一个ReturnCallback并设置到RabbitTemplate中

rabbitTemplate.setMandatory(true); rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {     String correlationId = message.getMessageProperties()             .getHeader(PublisherCallbackChannel.RETURNED_MESSAGE_CORRELATION_KEY);     log.debug("消息:{} 发送失败, 应答码:{} 原因:{} 交换机: {}  路由键: {}", correlationId,             replyCode, replyText, exchange, routingKey); });

当消息成功投递到交换机但是无法匹配到队列时:

- Publishing message [(Body:'"hello"' MessageProperties [headers={spring_listener_return_correlation=155648bd-fc3e-4c8b-a650-7b1ce720c7a6, spring_returned_message_correlation=7029ee49-357a-42fc-8532-dc41b4bb8e87, __TypeId__=java.lang.String}, contentType=application/json, contentEncoding=UTF-8, contentLength=7, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])] on exchange [DIRECT_EXCHANGE], routingKey = [DIRECT_ROUTING_KEY2]  - 消息:7029ee49-357a-42fc-8532-dc41b4bb8e87 发送失败, 应答码:312 原因:NO_ROUTE 交换机: DIRECT_EXCHANGE  路由键: DIRECT_ROUTING_KEY2 - 消息发送到exchange成功,id: 7029ee49-357a-42fc-8532-dc41b4bb8e87

从上面我们也可以看出ReturnCallback只处理投递到队列失败的情况,并不像ConfirmCallback既能处理失败的情况也能处理成功的情况。

"RabbitMQ是怎么确定消息是否投递到队列中的"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

消息 交换机 队列 情况 处理 成功 原因 路由 机制 内容 接口 更多 模式 知识 逻辑 输出 选择 验证 实用 学有所成 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全总结和展望 群体感应淬灭数据库 数据库安全与恢复案例 git修改文件上传服务器 党校为什么要购买数据库 遵化媒体网络技术售后保障 计算机网络安全特征有哪些 少女前线服务器安全 万方数据库登陆不进去 华为服务器亮红灯是什么意思 小公司如何搭建网络安全 陕西超频服务器供应商家 数据库文件和虚拟机太大 网络安全风险防范方案 java做软件开发好还是c 常见车型的技术数据库 重邮网络安全的老师 网络安全最大内部威胁 实时数据库生产 数据库安保等级测评有什么问题 在科技时代的发展中互联网 党校为什么要购买数据库 存储服务器数据流存储过程 ui软件开发工程师招聘 网络安全防范教育的问卷 珠海支付软件开发公司 怎么关闭闲鱼网络安全的推送 天津虚拟主机提供商云空间服务器 服务器风扇控制 投资者适当性评估数据库
0