RabbitMq——发布确认高级和消息回退

2023-11-19

发布确认高级:消息在传递过程中,我们需要确定消息状态信息,开启发布确认高级模式,消息传递结束后会返回传递结果信息,若发送失败的消息,该消息会被存入缓存中,定时任务发送失败消息,交换机收到消息后,缓存会删除该信息。

如果只开启发布确认模式的话,当交换机收到生产者发送的消息后,会发布确认消息给生产者,如果发现路由不通,则会直接丢弃消息,此时生产者处于不知情状态,就会造成消息丢失。

消息回退:通过设置 mandatory 参数可以在当消息传递过程中不可达目的地时将消息返回给生产者,好让生产者做后续 。

案例:生产者发送两条消息,一条通过路由confirm发送,一条通过路由unknow发送,如下图

1、配置properties文件,开启发布确认高级和消息回退


spring.rabbitmq.host=192.168.22.129
spring.rabbitmq.port=5672
spring.rabbitmq.username=user
spring.rabbitmq.password=123456
#发布消息成功到交换机后会触发回调方法
spring.rabbitmq.publisher-confirm-type=correlated
#路由不通,回退消息给生产者
spring.rabbitmq.publisher-returns=true

2、创建配置类声明交换机,队列,以及绑定交换机和队列

        (1)声明交换机,队列;

        (2)调用BindingBuilder.bind(队列名).to(交换机名).with(绑定路由)绑定交换机与队列

@Configuration
public class ConfirmConfigs {

    //交换机,队列,路由名
    public final static String CONFIRM_EXCHANGE="confirm_exchange";
    public final static String CONFIRM_QUEUE="confirm_queue";
    public final static String CONFIRM_ROUTING_KEY="confirm";

    //声明交换机,队列
    @Bean
    public DirectExchange confirmExchange(){
        return ExchangeBuilder.directExchange(CONFIRM_EXCHANGE).durable(true).build();
    }
    @Bean
    public Queue confirmQueue(){
        return QueueBuilder.durable(CONFIRM_QUEUE).build();
    }

    //绑定交换机和队列
    @Bean
    public Binding queueBindExchange(@Qualifier("confirmExchange") DirectExchange exchange,
                                     @Qualifier("confirmQueue") Queue queue){
        return BindingBuilder.bind(queue).to(exchange).with(CONFIRM_ROUTING_KEY);
    }
}

3、实现RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback接口,实现两个回调函数:

(1)confirm方法:交换机不管有无收到消息都会回调

        第一个参数:保存消息id以及相关信息;

        第二个参数:交换机是否收到消息,收到未true

        第三个参数:消息接收不到原因,成功接收消息则为null

 (2)returnMessage()方法:消息无法路由时会被回调

        第一个参数:被退回到消息体

        第二个参数:错误编码

        第三个参数:消息接收失败原因

        第四个参数:发送消息到交换机

        第五个参数:路由

@Component
@Slf4j
public class MyCallBacks implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {
   @Autowired
   private RabbitTemplate rabbitTemplate;

    //注入
    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        String id=correlationData!=null?correlationData.getId():"";
        if (b){
            //消息成功发送
            log.info("交换机已经收到id为:{}的消息",id);
        }else {
            //消息发送失败
            log.info("交换机未收到id为:{}的消息,收不打原因为:{}",id,s);
        }
    }

    @Override
    public void returnedMessage(Message message, int replayCode, String replayText, String exchange, String routingKey) {
        log.info("消息:{},被{}交换机退回,路由为:{},被退回原因为:{}",new String(message.getBody()),exchange,routingKey,replayText);
    }
}

4、生产者发送消息

        (1)创建CorrelationDate(消息id)对象,用于存放消息id以及相关信息

        (2)调用convertAndSend(交换机,路由,消息,CorrelationDate对象)方法发送消息

@Slf4j
@RestController
public class Producer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //发送消息
    @RequestMapping("/producer/{message}/{routing}/{id}")
    public void send(@PathVariable String message,
                       @PathVariable String routing,
                       @PathVariable String id){
        //存放消息id和相关信息
        CorrelationData correlationData = new CorrelationData(id);

        rabbitTemplate.convertAndSend(ConfirmConfigs.CONFIRM_EXCHANGE,
                routing, message,correlationData);

        log.info("生产者发送消息内容为:'{}',消息id为:{},发送路由为:{}",message,id,routing);
    }

}

5、注册监听器监听队列confirm_queue,接收消息

@Component
@Slf4j
public class Consumers {

    //消费者
    @RabbitListener(queues = ConfirmConfigs.CONFIRM_QUEUE)
    public void consumer(Message message){
        log.info("consumer收到消息:'{}',路由为:{}",
                new String(message.getBody()), message.getMessageProperties().getReceivedRoutingKey());
    }

}

6、测试,发送两条消息:

发送消息:吃饭了吗,路由为:confirm

发送消息:跑步了吗,路由为:confirms

 可以发现,消息:跑步了吗被退回,因为路由confirms不通,消息:吃饭了吗成功接收

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RabbitMq——发布确认高级和消息回退 的相关文章

  • 在java Swing中创建带有递增和递减按钮的数字文本框

    如何在 java swing 中创建一个数字文本框 它有两个按钮 向上和向下 分别递增和递减文本框中的值 此文本框也必须可编辑仅数字值 像这样的东西 我尝试在文本框附近放置两个按钮 然后在单击按钮时手动执行操作 有没有其他方法可以更好地做到
  • CopyOnWriteArraySet.add 和 remove 的重写等于

    我有像下面这样的课程 class A Override public boolean equals Object other return true Class B extends A Class C extends A Override
  • 如何安装 C++ 的 VOCE?

    我正在尝试安装 VOCE api 它是为 C 和 Java 构建的语音识别 API 这是我第二次使用外部 C 库 也是第一次使用 Java C api 语音链接 http voce sourceforge net http voce sou
  • 为什么 DragHandler exportAsDrag 禁用我的 MouseMotionListener?

    我想实现一个简单的 JComponent 拖放 并带有 O Reilly Swing Hacks 的预览 我的问题是 如果 TransferHandler 启动 Drag MouseMotionListener 停止执行 mouseDrag
  • 无法让远程 EJB 与 Wildfly 上的 EJB 客户端 API 配合使用

    我目前正在努力让远程 EJB 调用在 wildfly 8 x 和 9 x 上工作 详细来说 它是关于使用 EJB 客户端 API 方法从独立客户端应用程序 而不是从另一个应用程序服务器 进行远程调用 远程命名方法适用于我 但不适用于我的场景
  • 将位于 jar 中的文件读取为 java.io.File 对象

    与此类似的问题已发布 但似乎没有一个答案对我的情况有帮助 我正在编写一个程序包 它使用 Google 的凭据来获取 Google Apps 用户 为此 我使用服务帐户 因此为了检索凭据 我需要提供 除其他外 一个 p12 签名文件 Cred
  • java“类文件包含错误的类”错误

    我正在尝试制作一个控制台应用程序来测试我的网络服务 我成功部署了一个网络服务http localhost 8080 WS myWS http localhost 8080 WS myWS我用 wsimport 制作了代理类 wsimport
  • 嵌套枚举是静态的吗?

    读书时这个问题 https stackoverflow com questions 25011061 why can enum implementations not access private fields in the enum cl
  • JavaPreparedStatementUTF-8字符问题

    我有一份准备好的声明 PreparedStatement st 在我的代码中 我尝试使用 st setString 方法 st setString 1 userName userName 的值为 ak a setString 方法将 ak
  • MAC OS 的 java.awt.Robot 类中出现无头环境错误

    我正在尝试使用 JavaFX 应用程序捕获屏幕截图Robot class 这是我在我的应用程序中使用的代码 Rectangle screenBounds new Rectangle Screen getPrimary getBounds g
  • Java中通过FTP创建文件夹层次结构

    Java 是否有现成的功能可以在远程 FTP 服务器上创建文件夹层次结构 Apache Commons 确实提供了 FTP 客户端 但我找不到创建目录层次结构的方法 它确实允许创建单个目录 makeDirectory 但创建整个路径似乎并不
  • 使用 eclipse 配置mockito 时出现问题。给出错误:java.lang.verifyError

    当我将我的mockito库添加到类路径中 并使用一个简单的mockito示例进行测试时 我尝试使用模拟对象为函数add返回错误的值 我得到java lang verifyerror 以下是用于测试的代码 后面是 logcat Test pu
  • Ubuntu 的打包 - Web 应用程序

    Web 应用程序没有与 C 或类似文件不同的 make 文件 但是 它需要放置在特定的目录中 例如 var www 我是 Linux 打包新手 所以我的问题是 如何将我的应用程序打包到 deb 中 以便在安装时将其放入 etc myprog
  • 当另一个线程发生事情时从主线程获取数据?

    目前我有一个线程正在运行一个侦听连接的套接字 当它收到连接时 它需要上传在主线程中收集的数据 即从主线程获取数据 但是 我传递了对象的实例 但它从未使用等待连接时收集的数据进行更新 有没有正确的方法来做到这一点 我用谷歌搜索了一下 似乎找不
  • Java中如何限制文件大小

    我正在我的应用程序中创建一个文件 并继续向该文件中写入一些内容 但是当我的文件达到一定大小 比如说 100 行 后 我想删除第一行并将新行写入底部 要求是我的文件应该受到限制 但它应该保留我写入文件的最新内容 请告诉我在Java中是否可行
  • servlet 如何获取 servlet 之外的文件的绝对路径?

    我们一直在使用 System getProperties user dir 来获取属性文件的位置 现在它已经部署在 Tomcat 上 通过 servlet 系统调用将位置指定为 tomcat 而不是属性文件所在的位置 我们如何动态调用属性文
  • JBoss 5 截断 base64 cookie 字符串的尾部 =

    从 JBoss 4 升级到 JBoss 5 后 我注意到最烦人的回归 它截断 base64 cookie 值的尾部等号 我花了很长时间才明白问题不是我的代码而是 JBoss 的 我用 google 搜索了一下 发现这是一个已知的问题issu
  • Spring 和 Hibernate 连接池

    如何使用 Spring 和 Hibernate 配置连接池 Thanks Venu 您可以使用 DBCP 组件
  • 错误:运算符不存在:整数 = 字符变化,使用 Postgres 8.2

    我有一个用旧版本的 Eclipse Ganymede 如果我没记错的话 开发的 Java EE Web 应用程序 我最近迁移到 Kubuntu 12 04 LTS 并将应用程序迁移到 Eclipse Kepler 我从 Eclipse 网站
  • 生成签名和加密的 JWT

    我正在尝试使用生成签名和加密的 JWT 令牌雨云智威汤逊 http connect2id com products nimbus jose jwt private void generateToken throws JOSEExceptio

随机推荐

  • Power BI:切片器联动的一些问题

    问题1 联动切片器选中子项后父项未能显示全部 如下所示 切片器原始状态为 Province和City来源同一张表 当选中了City中的某一项时 变为 父项也发生了变化 但我们希望无论子项选择什么 父项应该始终显示全部 解决办法 City切片
  • javaweb本地启动很快,服务器上面启动特别慢

    在JVM环境中解决 打开 JAVA PATH jre lib security java security这个文件 找到下面的内容 securerandom source file dev urandom替换成 securerandom s
  • 卷麻了,00后测试用例写的比我还好,简直无地自容......

    经常看到无论是刚入职场的新人 还是工作了一段时间的老人 都会对编写测试用例感到困扰 例如 如何编写测试用例 作为一个测试新人 刚开始接触测试 对于怎么写测试用例很是头疼 无法接触需求 只能站在用户角度去做测试 但是这样情况会导致不能全方位测
  • python中深拷贝与浅拷贝的详细解释

    在Python中 当我们对一个对象进行拷贝时 有两种方式 浅拷贝和深拷贝 浅拷贝创建了一个新的对象 其中包含原始对象的引用 而深拷贝则创建了一个完全独立的新对象 其中包含原始对象所有数据的副本 这意味着在原始对象和拷贝对象之间进行更改时 浅
  • 小记 Java stream 中 peek()

    peek 函数 接受一个函数作为参数 这个函数会被应用到每个元素上 并将结果元素映射成一个新的元素 相比于类似 foreach 更类似于lambda中的map函数 map函数 接受一个函数作为参数 这个函数会被应用到每个元素上 并将返回值映
  • ElementUI的自定义模板

    ElementUI自定义模板的使用 前言 一 ElementUI的Input重要属性 二 使用步骤 1 上实例 转自Element官网 2 介绍几个重要参数方法 3 基于以上的介绍 做一个带提示的搜索输入框 总结 前言 ElementUI对
  • 一个java程序员4年4个工作的经历

    今天看到一个帖子说程序员怎么提升自己的技能 里面说了十多项 对自己感觉能有用的有以下几点 读书 读代码 读博客 写博客 回答别人的问题 参加一个开源项目 参加培训 研讨会 回答问题当中给自己的思考 一个毕业生 做java转正了4k 一个室友
  • 为什么要选择云原生数据库

    为什么要选择云原生数据库 前言 1 传统数据库 1 1 传统数据库概念 1 2 传统数据库优缺点 1 2 1 优点 1 2 2 缺点 2 云原生数据库 2 1 云原生数据库概念 2 2 云化代表未来 2 3 云原生数据库的优势 2 3 1
  • 【MATLAB】字符串的处理及矩阵的初步学习

    欢迎访问我的个人网站 reality2ideal xyz 内容在CSDN和个人网站上同步更新 字符串处理 字符串矩阵 gt gt ch 123456 qwerty ch 2 6 char 数组 123456 qwerty 字符串矩阵的列数要
  • 转载:R语言绘图—图形标题、坐标轴设置

    R语言绘图是通过函数命令及相应参数设置实现的 如plot x y plot为绘图函数命令 x y则是绘图参数 指定了绘图的数据向量 但这种最基本的绘图设置很难满足个性化绘图的要求 我们需要根据需要对图形元素进行设置 图形元素是各类图形的基本
  • 生成带干扰线的验证码

    import java awt Color import java awt Font import java awt Graphics2D import java awt Transparency import java awt image
  • vue吸顶导航栏_vue2组件系列第四十二节:NavBar 导航栏

    NavBar就是程序顶部的内容 相当于网站里的面包屑的作用 准备工作 创建一个页面 NavBar vue 在router js里配置NavBar页面的路由 path navbar name navbar component gt impor
  • 左右手坐标系区别和联系

    本文是分析 所谓的右手坐标系转换为左手坐标系需要的 z轴取反 x轴取反 或者改变摄像机位置 渲染绕序改变 其中的进一步的原因 参考文章 https msdn microsoft com en us library bb204853 28VS
  • 真伪定时器

    首先观察一下下面两组代码区别在哪里 第一组代码 setInterval gt 1 5s 的同步逻辑 1000 第二组代码 function fn setTimeout gt 1 5s 的同步逻辑 fn 1000 fn 两组代码都有定时功能
  • Java实体类详解及使用方法

    在Java编程中 实体类 Entity Class 是一种经常使用的类类型 实体类用于表示真实世界中的对象 通常与数据库中的表格相对应 本文将详细介绍Java实体类的概念 特点以及使用方法 什么是实体类 实体类是指用于表示和存储真实世界中的
  • 【论文精读】A view-free image stitching network based on global homography-基于全局单应的无视图图像拼接网络

    论文链接地址 代码链接地址 关于本文的代码 我已经调试过了 在调试过程中遇到的错误 我也做了一些总结 有需要的可以参考这篇博文 A view free image stitching network based on global homo
  • Spring Boot集成控制反转

    Most of the time dependency injection is the first thing that comes to mind whenever the concept of inversion of control
  • idea 2021.1安装 与 常用配置

    前置说明 该文档是基于idea 2021 1版本编写的 一 下载安装 官方下载地址 https www jetbrains com idea download other html 二 常用的设置 显示工具栏 设置tab选项卡换行 设置代码
  • Unity 打开时一直busy怎么办

    查看网络连接 比如360流量球或者任务管理器内的网络 如果能看到unity在下载东西或网络占用高 则表明可能是unity在下载在线资源 查看 工程目录 Package manifest json 文件是否存在国外地址 可能是由于网络原因连不
  • RabbitMq——发布确认高级和消息回退

    发布确认高级 消息在传递过程中 我们需要确定消息状态信息 开启发布确认高级模式 消息传递结束后会返回传递结果信息 若发送失败的消息 该消息会被存入缓存中 定时任务发送失败消息 交换机收到消息后 缓存会删除该信息 如果只开启发布确认模式的话