rabbitMQ发布确认-交换机不存在或者无法抵达队列的缓存处理
rabbitMQ在发送消息时,会出现交换机不存在(交换机名字写错等消息),这种情况如何会退给生产者重新处理?【交换机层】
生产者发送消息时,消息未送达到指定的队列,如何消息回退?
核心:对类RabbitTemplate.ConfirmCallback 和RabbitTemplate.ReturnCallback的重写。
RabbitTemplate.ConfirmCallback:交换机在收到消息或者没收到消息时会被触发
RabbitTemplate.ReturnCallback:消息进入交换机,不能达到指定目的地时被出发。
开启交换机确认
开启消息不可达回退
配置文件不开启 这两项
spring:rabbitmq:
# 交换机进行确认消息publisher-confirm-type: correlated
# 交换机不可以路由消息时 消息回退publisher-returns: true
配置类声明
package com.esint.configs;import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 发布确认**/
@Configuration
public class ConfirmConfig {//交换机public static final String CONFIRM_EXCHANGE = "confirm.exchange";//队列public static final String CONFIRM_QUEUE = "confirm.queue";//routing-keypublic static final String CONFIRM_ROUTING_KEY = "key1";//声明 交换机@Bean("confirmExchange")public DirectExchange confirmExchange(){return new DirectExchange(CONFIRM_EXCHANGE);}//声明 队列@Bean("confrimQueue")public Queue confrimQueue(){return QueueBuilder.durable(CONFIRM_QUEUE).build();}//绑定@Beanpublic Binding queueBindingExchange(@Qualifier("confrimQueue") Queue confrimQueue,@Qualifier("confirmExchange") DirectExchange confirmExchange){return BindingBuilder.bind(confrimQueue).to(confirmExchange).with(CONFIRM_ROUTING_KEY);}
}
消费者:
package com.esint.controller;import com.esint.configs.ConfirmConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RestController
@RequestMapping("/confirm")
public class ProducerController {@Autowiredprivate RabbitTemplate rabbitTemplate;//发消息@GetMapping("/sendMessage/{message}")public void sendMessage(@PathVariable String message){//普通发送模式 无是否发送成功回调CorrelationData correlationData = new CorrelationData("101");rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE,ConfirmConfig.CONFIRM_ROUTING_KEY+"123",message);log.info("发送消息为:{}",message);}}
消费者:
package com.esint.consumer;import com.esint.configs.ConfirmConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class Consumer {@RabbitListener(queues = ConfirmConfig.CONFIRM_QUEUE)public void receiveConfrimMessage(Message message){log.info("接收到的消息为:" + new String(message.getBody()));}
}
核心修改的重写的类:
package com.esint.consumer;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;@Slf4j
@Component
public class MyCallBack implements RabbitTemplate.ConfirmCallback ,RabbitTemplate.ReturnCallback{/*** 注入:本类为实现了RabbitTemplate的内部类,所以在RabbitTemplate发送消息的时候不会调用到我们自己的实现,所以需要把这个类在注入到RabbitTemplate中。*/@Autowiredprivate RabbitTemplate rabbitTemplate;@PostConstructpublic void init(){rabbitTemplate.setConfirmCallback(this);rabbitTemplate.setReturnCallback(this);}/*** RabbitTemplate.ConfirmCallback 是在【生产者】发送【交换机】 交换机的感知回应调去方法** 交换机确认回调方法* 1.交换机接收消息成功* 参数1 correlationData保存了回调消息ID和相关信息* 参数2 交换机收到消息 true* 参数3 失败原因 为 null* 2.交换机接受消息失败* 参数1 correlationData保存了回调消息ID和相关信息* 参数2 交换机收到消息 false* 参数3 失败原因* @param correlationData 来源于生产者 所以在发消息时 需要带有这个属性* @param ack* @param cause*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {String id = correlationData != null ? correlationData.getId() : "";if(ack){log.info("交换机确认收到 ID:{}" ,id);}else {log.info("交换机未收到ID:{}的消息,原因:{}",id,cause);//这里实现发送交换机失败的存储逻辑}}/*** 回退消息* 在消息传递过程不可达目标地时 返还给生产者 只有消息不可达,才会执行这个方法** @param message* @param replyCode* @param replyText* @param exchange* @param routingKey*/@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {log.error("消息{} 被交换机{} 退回,原因:{} 路由:{}",new String(message.getBody()),exchange,replyText,routingKey);//这里实现发送消息不到达的逻辑 发送消息无法被逻辑 默认就会被交换机丢掉 这里重写后 可以在这里处理存储}
}
故意发送一个错误路由时:

消息能发出 交换机有确认 消息可以被回退
相关文章:
rabbitMQ发布确认-交换机不存在或者无法抵达队列的缓存处理
rabbitMQ在发送消息时,会出现交换机不存在(交换机名字写错等消息),这种情况如何会退给生产者重新处理?【交换机层】 生产者发送消息时,消息未送达到指定的队列,如何消息回退? 核心&…...
STM32 MAP文件
文章目录 1 生成Map2 map中概念3 文件分析流程3.1 Section Cross References3.2 Removing Unused input sections from the image(移除未使用的段)3.3 Image Symbol Table 映像符号表3.4 Memory Map of the image(映像的内存分布)…...
云原生Kubernetes系列 | Kubernetes静态Pod的使用
云原生Kubernetes系列 | Kubernetes静态Pod的使用 静态pod不建议在master上操作,因为master上跑的是集群核心静态pod,如果配置失败,会导致集群故障。建议在knode1或knode2上去做。 kubernetes master节点上的核心组件pod其实都是静态pod: [root@k8s-master ~]# ls /etc/ku…...
二次创作Z01语言
目录 一,字符集 二,编译分词 三,token含义 四,Z01翻译成C 五,执行翻译后的代码 六,打印Hello World! 一,字符集 假设有门语言叫Z01语言,代码中只有0和1这两种字符。 二&#…...
【蓝桥杯国赛真题28】Scratch行驶的汽车 少儿编程图形化编程 中小学生第十四届蓝桥杯scratch国赛真题讲解
目录 scratch行驶的汽车 一、题目要求 编程实现 二、案例分析 1、角色分析...
LeetCode Hot100 236.二叉树的最近公共祖先
题目: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节…...
ERROR: Could not find a version that satisfies the requirement torch
在windows 上安装pip install torch torchvision torchaudio 报错: ERROR: Could not find a version that satisfies the requirement torch (from versions: none) ERROR: No matching distribution found for torch 解决办法: 将python版本降到3.11…...
2009年iMac装64位windows7及win10
2009年iMac装64位windows7及win10 Boot Camp没有“创建 Windows7 或更高版本的安装磁盘”选项 安装完Mac OS系统后,要制作Windows7安装U盘时才发现,Boot Camp没有“创建 Windows7 或更高版本的安装磁盘”选项,搜索到文章:修改Boo…...
(三) Windows 下 Sublime Text 3 配置Python环境和Anaconda代码提示
一:新建一个 Python3.7 编译环境。 1 Tools--Build System--New Build System... 修改前: 修改后: 内容: {"cmd":["C:\\Python\\Python37-32\\python.exe","-u","$file"],"file_r…...
【shell脚本】一些简单的shell脚本案例,mark一下
1、使用变量生成随机密码 比如自定义密码里面是数字和字母(或者还可以是某些符号等),随机生成一个想要的多少位的密码 [root@localhost test]#vim mima.sh #!/bin/bash str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPKRSTUVWXYZ0123456789" for i in {1..6} …...
Android Studio记录一个错误:Execution failed for task ‘:app:lintVitalRelease‘.
Android出现Execution failed for task :app:lintVitalRelease.> Lint found fatal errors while assembling a release target. Execution failed for task :app:lintVitalRelease解决方法 Execution failed for task ‘:app:lintVitalRelease’ build project 可以正常执…...
计算机组成原理4
1.汇编语言 2.汇编语言常见的运算指令 3.AT&T格式 和 Intel格式 4.跳转指令 5.cmp比较的底层原理 6.函数调用的机器级表示 7.CISC和RISC...
【人工智能】Chatgpt的训练原理
前言 前不久,在学习C语言的我写了一段三子棋的代码,但是与我对抗的电脑是没有任何思考的,你看了这段代码就理解为什么了: void computerMove(char Board[ROW][COL], int row, int col) {while (1){unsigned int i rand() % ROW, …...
一文讲明SpringMVC 【爆肝整理一万五千字】
我 | 在这里 🕵️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 🏠 工作 | 广州 ⭐ Java 全栈开发(软件工程师) 🎃 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 ✈️已经旅游的地点 | 新疆-乌鲁木齐、新疆-吐鲁番、广东-广州…...
【Python爬虫实战项目】ip代理池项目原理及代码解析
视频讲解链接:https://www.bilibili.com/video/BV1e8411r7xX/ 代码链接:https://github.com/w-x-x-w/Spider-Project 大家好,这一季我们来介绍一个Python爬虫实战项目-ip代理池项目,这一集我们会首先介绍ip代理池的工作原理流程&a…...
Ardupilot开源飞控之VTOL之旅:配件规格
Ardupilot开源飞控之VTOL之旅:配件规格 1. 源由2. 飞控板 Aocoda-RC H743Dual3. PDB分电板 Aocoda-RC PDB30604. GPS BN8805. 摄像头 RunCam 1200TVL6. 模拟图传 JHEMCU RuiBet Tran-3016W 5.8GHZ 1.6W7. 打印件7.1 飞控/GPS座子7.2 VTX/天线座子7.3 接收机天线座 8…...
Binlog vs. Redo Log:数据库日志的较劲【基础】
🎏:你只管努力,剩下的交给时间 🏠 :小破站 Binlog vs. Redo Log:数据库日志的较劲 前言第一:Binlog与Redo Log的基础概念Binlog(二进制日志)的基础概念Redo Logÿ…...
代理模式-C语言实现
UML图: 代码实现: #include <stdio.h>// 抽象主题接口 typedef struct {void (*request)(void*); } Subject;// 具体主题类 typedef struct {void (*request)(void*); } RealSubject;void RealSubject_request(void* obj) {printf("RealSubj…...
解密 sqli靶场第一关:一步一步学习 SQL 注入技术
目录 一、判断是否存在注入点 二、构造类似?id1 --的语句 三、判断数据表中的列数 四、使用union联合查询 五、使用group_concat()函数 六、爆出数据库中的表名 七、爆出users表中的列名 八、爆出users表中的数据 🌈嗨!我是Filotimo__🌈。很…...
Flask 使用Jinja2模板引擎
Jinja2,由Flask框架的创作者开发,是一款功能丰富的模板引擎,以其完整的Unicode支持、灵活性、高效性和安全性而备受推崇。最初受Django模板引擎启发,Jinja2为Flask提供了强大的模板支持,后来也成为其他项目的首选。在本…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
