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…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...
Razor编程中@Helper的用法大全
文章目录 第一章:Helper基础概念1.1 Helper的定义与作用1.2 Helper的基本语法结构1.3 Helper与HtmlHelper的区别 第二章:基础Helper用法2.1 无参数Helper2.2 带简单参数的Helper2.3 带默认值的参数2.4 使用模型作为参数 第三章:高级Helper用法…...
