RabbitMQ高级特性 - 生产者消息确认机制
文章目录
- 生产者消息确认机制
- 概述
- confirm 代码实现
- return 代码实现
生产者消息确认机制
概述

为了保证信息 从生产者 发送到 队列,因此引入了生产者的消息确认机制.
RabbitMQ 提供了两种解决方案:
- 通过事务机制实现.
- 通过发送确认机制(confirm 和 return)实现.
因为事务机制比较消耗性能,在实际工作中用的也不多,因此这里主要介绍 confirm 和 return 机制来实现发送放的确认.
a)confirm 确认模式

如上图,confirm 确认模式主要保障于 生产者 到 交换机 的消息可靠性.
具体的,在生产者发送消息之前,给 RabbitTemplate 设置一个 ConfirmCallback 回调监听:
- 如果 Exchange
成功收到消息,那么 ConfirmCallback 这个回调 ack 参数就为true - 如果 Exchange
没有收到消息,那么 ConfirmCallback 这个回调 ack 参数就为false
b)return 退回模式

如上图,confirm 确认模式主要保障于 交换机 到 队列 的消息可靠性.
具体的,在生产者发送消息之前,给 RabbitTemplate 设置一个 ReturnsCallback 回调监听:
- 如果 Queue
成功收到 Exchange 的消息,那么 ReturnsCallback 回调监听就不会收到任何消息. - 如果 Queue
没有收到 Exchange 的消息,那么 ReturnsCallback 回调监听就会收到该消息.
confirm 代码实现
a)配置文件
spring:application:name: rabbitmqrabbitmq:host: env-baseport: 5672username: rootpassword: 1111publisher-confirm-type: correlated # 开启发送方确认机制
b)交换机、队列、绑定配置
@Bean("confirmExchange")fun confirmExchange() = DirectExchange(MQConst.CONFIRM_EXCHANGE)@Bean("confirmQueue")fun confirmQueue() = Queue(MQConst.CONFIRM_QUEUE)@Bean("confirmBinding")fun confirmBinding(@Qualifier("confirmExchange") exchange: DirectExchange,@Qualifier("confirmQueue") queue: Queue,): Binding = BindingBuilder.bind(queue).to(exchange).with(MQConst.CONFIRM_BINDING)
c)confirmRabbitTemplate Bean 配置
@Configuration
class MQTemplateConfig {/*** 这个配置一定要有!!!(或者有大于等于 2 个的 RabbitTemplate Bean)** 这是由于 Autowired 注解自身的原因(以 rabbitmq 为例):* 如果配置文件中配置 rabbitmq 相关连接信息,那么 spring 会自动为其创建 RabbitTemplate Bean 对象* 如果配置文件中配置 rabbitmq 相关连接信息,而且代码中也配置了一个 RabbitTemplate 的 Bean(名称为 confirmRabbitTemplate),那么 Spring 将不会自动配置默认的 RabbitTemplate Bean 对象* 这就导致,我们无论代码写的注入的是 rabbitTemplate 还是 confirmRabbitTemplate,但实际上注入的都是 confirmRabbitTemplate*/@Bean("rabbitTemplate")fun rabbitTemplate(connectionFactory: ConnectionFactory): RabbitTemplate {return RabbitTemplate(connectionFactory)}@Bean("confirmRabbitTemplate")fun confirmRabbitTemplate(connectionFactory: ConnectionFactory): RabbitTemplate {val tpl = RabbitTemplate(connectionFactory)tpl.setConfirmCallback(RabbitTemplate.ConfirmCallback { correlationData, ack, cause ->println("执行了 confirm ...")if (ack) {println("confirm ack: { 消息id: ${correlationData?.id} }")} else {println("confirm nack: { 消息id: ${correlationData?.id}, cause: $cause }")//进行相应的业务处理...}})return tpl}}
d)生产者接口
@RestController
@RequestMapping("/mq")
class MQApi(val confirmRabbitTemplate: RabbitTemplate
) {@RequestMapping("/confirm")fun confirm(): String {val data = CorrelationData("1")confirmRabbitTemplate.convertAndSend(MQConst.CONFIRM_EXCHANGE, MQConst.CONFIRM_BINDING, "confirm msg 1", data)return "ok"}}
此处演示无需消费者…
e)消息正确的路由到交换机,效果如下:


f)消息没有找到交换机(发送消息时,写了一个不存在的交换机的名字),效果如下:


return 代码实现
a)配置文件
spring:application:name: rabbitmqrabbitmq:host: env-baseport: 5672username: rootpassword: 1111publisher-confirm-type: correlated # 开启发送方确认机制
b)bean 的配置
@Configuration
class MQTemplateConfig {/*** 这个配置一定要有!!!(或者有大于等于 2 个的 RabbitTemplate Bean)** 这是由于 Autowired 注解自身的原因(以 rabbitmq 为例):* 如果配置文件中配置 rabbitmq 相关连接信息,那么 spring 会自动为其创建 RabbitTemplate Bean 对象* 如果配置文件中配置 rabbitmq 相关连接信息,而且代码中也配置了一个 RabbitTemplate 的 Bean(名称为 confirmRabbitTemplate),那么 Spring 将不会自动配置默认的 RabbitTemplate Bean 对象* 这就导致,我们无论代码写的注入的是 rabbitTemplate 还是 confirmRabbitTemplate,但实际上注入的都是 confirmRabbitTemplate*/@Bean("rabbitTemplate")fun rabbitTemplate(connectionFactory: ConnectionFactory): RabbitTemplate {return RabbitTemplate(connectionFactory)}@Bean("confirmRabbitTemplate")fun confirmRabbitTemplate(connectionFactory: ConnectionFactory): RabbitTemplate {val tpl = RabbitTemplate(connectionFactory)tpl.setConfirmCallback(RabbitTemplate.ConfirmCallback { correlationData, ack, cause ->println("执行了 confirm ...")if (ack) {println("confirm ack: { 消息id: ${correlationData?.id} }")} else {println("confirm nack: { 消息id: ${correlationData?.id}, cause: $cause }")//进行相应的业务处理...}})//这里可以和 confirm模式 一起配置//mandatory = true 属性是在告诉 rabbitmq,如果一个消息无法被任何队列消费,那么该消息就会返回给发送者,此时 ReturnCallback 就会被触发//mandatory 相当于是开启 ReturnsCallback 前提tpl.setMandatory(true)tpl.setReturnsCallback(RabbitTemplate.ReturnsCallback { returned ->println("执行了 return ...")println("return: $returned")})return tpl}}
c)生产者接口
@RestController
@RequestMapping("/mq")
class MQApi(val confirmRabbitTemplate: RabbitTemplate
) {@RequestMapping("/confirm")fun confirm(): String {val data = CorrelationData("1")confirmRabbitTemplate.convertAndSend(MQConst.CONFIRM_EXCHANGE, MQConst.CONFIRM_BINDING, "confirm msg 1", data)return "ok"}}
d)正确的路由到队列,效果如下:
可以看到只有 confirm模式 被触发.

e)没有路由到队列(发送消息时,我改成了一个不存在的 routingKey 名字),效果如下:


相关文章:
RabbitMQ高级特性 - 生产者消息确认机制
文章目录 生产者消息确认机制概述confirm 代码实现return 代码实现 生产者消息确认机制 概述 为了保证信息 从生产者 发送到 队列,因此引入了生产者的消息确认机制. RabbitMQ 提供了两种解决方案: 通过事务机制实现.通过发送确认机制(confi…...
webpack的loader机制
webpack的loader机制 loader本质上就是导出函数的JavaScript模块。导出的函数,可以用来实现内容的转换。 /* * param{string|Buffer} content 源文件的内容 * param{object} [map] SourceMap数据 * param{any} [meta] meta数据,可以是任何数据 * */ fu…...
(STM32笔记)十一、通过EXTI外部中断实现 按键控制LED
我用的是正点的STM32F103来进行学习,板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。 十一、通过EXTI外部中断实现 按键控制LED 十一、通过EXTI外部中断实现 按键控制LED1、按键模块按键原理图按键程序思路 2、中…...
假如家里太大了,wifi连不上了怎么办
最近有个土豪朋友抱怨,他家里太大了,一个路由器的Wi-Fi信号根本无法覆盖他们家的每个房间,都没办法上网看奥运会比赛了。(还好我是穷人,就没有这种烦恼T_T)。 然后我问他为何不用一个路由器作主路由器&…...
elementPlus 设置el-input文本域固定高度和禁止下拉
elementPlus 设置el-input文本域固定高度和禁止下拉 话不多说直接上代码 // resize"none" 禁止下拉<el-inputv-model"textarea"style"width: 240px"type"textarea"resize"none"placeholder"请输入"/>// 设…...
(转)领导人必过的三道关
为什么企业领导人享受优厚的待遇,为什么董事会对企业领导人千挑万选?因为企业生命如此脆弱,据美国《财 富》杂志报道,世界500强企业平均寿命40年,世界1000强企业平均寿命30年,一般跨国公司平均寿命10年。而就是这脆弱…...
速盾:cdn可以定时刷新缓存吗?
CDN(Content Delivery Network)是一种通过在全球各地分布的服务器上缓存和传送网站内容的技术,以提高用户访问速度和降低服务器负载。CDN的缓存机制可以减少用户对源服务器的请求次数,从而提高网站的响应速度和性能。但是…...
代码随想录算法训练营第二十九天| 62.不同路径、63. 不同路径 II
写代码的第二十九天 继续动归!!! 62.不同路径 思路 解决问题1:dp[i][j]的的含义是什么?本题给的是一个二维的表,判断从左上角走到右下角有多少种路径,所以dp应该是二维数组,dp[i]…...
Go+Redis零基础到用户管理系统API实战_20240730 课程笔记
概述 如果您没有Golang的基础,应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227 基础不好的同学每节课的代码最好配合视频进…...
ScreenAgent:基于LVLM的计算机控制智能体
ScreenAgent : A Vision Language Model-driven Computer Control Agent 论文链接: https://arxiv.org/abs/2402.07945https://arxiv.org/abs/2402.07945IJCAI 2024 1.概述 大型语言模型(LLM),诸如ChatGPT与GPT-4,在自然语言处理领域(涵盖生成、理解及对话等任务)展现出…...
谷粒商城实战笔记-129-商城业务-商品上架-nested数据类型场景
文章目录 扁平化处理扁平化处理导致的检索问题 解决方案:使用 nested 结构 在es的数据类型中有一个nested类型,本讲将重点讨论这个类型。 扁平化处理 PUT my_index/doc/1 {"group" : "fans","user" : [{"first&quo…...
axios请求响应拦截器
目录 axios-拦截器 拦截器的作用 请求拦截器-基本写法: axios请求拦截器-统一设置token 需求: 核心步骤: 关键代码: 响应拦截器-基本写法: axios响应拦截器-统一处理token失效 需求: 核心步骤: 关键代码: axios响应拦截器-数据剥离 需求: 核心步骤: 关键代码: ax…...
Python 中单例模式实现的几种方式
在设计模式中,单例模式是经常被提及和使用的一种模式。它保证一个类只有一个实例,并提供全局访问点。在Python中,有多种实现单例模式的方法。那么,如何选择合适的方法来实现单例模式呢? 单例模式在Python中的几种实现方…...
mysql数据库触发器同步数据
首先检查数据源库是否支持触发器,show ENGINES,如果FEDERATED是NO,表示未开启,如需开启,再mysql配置文件中,添加federated配置到mysqld下面。 一、同服务器不同库触发器同步,这里只举例插入数据…...
Prometheus-v2.45.0+Grafana+邮件告警
目录 普罗米修斯监控架构介绍 Prometheus 监控架构 1. 数据抓取(Scraping) 2. 时序数据库(TSDB) 3. 数据模型 4. PromQL 查询语言 5. 告警(Alerting) 6. Alertmanager 7. 可视化(Visu…...
LeetCode——572. 另一颗树的子树
通过万岁!!! 题目:给你两棵树,然后问subRoot是不是root的子树。也就是root某个节点的所有孩子节点在值和结构上完全与subRoot相同。思路:我的思路比较简单,就是遍历root,遇到root中…...
Spring Boot整合MyBatis-Flex
说明:MyBatis-Flex(官网地址:https://mybatis-flex.com/),是一款数据访问层框架,可实现项目中对数据库的访问,类比MyBatis-Plus。本文介绍,在Spring Boot项目整合MyBatis-Flex。 创…...
重塑未来体验:边缘计算与云原生的完美邂逅
🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、云原生的兴起 2、边缘计算的兴起 二、边缘计算基础 …...
浅谈基础数论(c++)
目录 一些常见的符号表示阶乘定理 快速幂模板题代码扩展:矩阵快速幂主要作用 欧拉函数扩展积性函数 欧拉函数求法筛选法求欧拉函数(积性函数) 扩展欧几里得裴蜀定理问题分析代码 问题分析 同余与逆元如何求解逆元扩展欧几里得 例题讲解X-Magi…...
jdk 17新特性 sealed 关键字
通俗理解 sealed 关键字就是给对象继承加了权限控制一样,你必须在我的规则范围内才可以继承我的类 使用 permits 关键字控制允许哪些子类继承 子类必须加以下三个关键字: final 最终继承类(继承到这个类就不允许再往下继承了)n…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
