前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot-RabbitMQ发送消息的监控

SpringBoot-RabbitMQ发送消息的监控

原创
作者头像
程序员NEO
发布于 2023-09-27 15:10:38
发布于 2023-09-27 15:10:38
3020
举报

概述

刚才我们发送消息,不管成功还是失败,都不报错,结果看效果时,发现有的没有发进去,那么如何知道消息是否发送成功呢,RabbitMQ提供了一个消费监视的功能。注意:RabbitMQ发送消息分为2个阶段,消息发送到交互机里面,可以监视,消息由交互机到队列里面,也可以监视。

创建项目

需要的依赖如下:

代码语言:html
AI代码解释
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.amqp</groupId>
        <artifactId>spring-rabbit-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

配置 application.yml,将原来的 properties 改一下后缀名就行,内容如下:

代码语言:yaml
AI代码解释
复制
server:
  port: 8080
spring:
  application:
    name: Springboot-RabbitMQ
  rabbitmq:
    username: user
    password: 123456
    host: 139.196.183.130
    port: 5672
    virtual-host: v-it6666
    # 开启消息到达交换机的确认机制
    publisher-confirm-type: correlated
    # 消息由交换机到达队列时失败触发
    publisher-returns: true

监控消息到达交换机

创建 ConfirmImpl 给 RabbitTemplate 设置消息到达交换机的回调对象,内容如下所示:

代码语言:java
AI代码解释
复制
/**
 * @author BNTang
 */
@Component
public class ConfirmImpl implements RabbitTemplate.ConfirmCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ConfirmImpl confirmImpl;

    @PostConstruct
    private void initRabbitTemplate() {
        this.rabbitTemplate.setConfirmCallback(confirmImpl);
    }

    /**
     * 消息到达交换机后,该方法会回调
     *
     * @param correlationData 相关的数据
     * @param ack             交换机是否接收成功
     * @param cause           如果没有接收成功,返回拒绝的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            System.out.println("交换机接收消息成功");
        } else {
            System.out.println("交换机接收消息失败,失败原因为:" + cause);
        }
    }
}

发送消息

代码语言:java
AI代码解释
复制
@SpringBootTest
class SpringbootRabbitmqApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    void contextLoads() {
        this.rabbitTemplate.convertAndSend("directs", "error", "error 的日志信息");
        System.out.println("消息发送成功");
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

监控消息由交换机到队列里面

创建 ReturnsImpl 给 RabbitTemplate 设置消息到达队列失败后回调对象,内容如下所示:

代码语言:java
AI代码解释
复制
/**
 * @author BNTang
 */
public class ReturnsImpl implements RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ReturnsImpl returnsImpl;

    @PostConstruct
    private void initRabbitMQ() {
        this.rabbitTemplate.setReturnCallback(returnsImpl);
    }

    /**
     * 当消息到达队列失败时,回调的方法,消息被退回了,我们可以把消息记录下来,分析错误的原因,以后重新发送,这样的话,消息就不会再丢失了
     *
     * @param message    消息
     * @param replyCode  回退的响应码
     * @param replyText  响应文本
     * @param exchange   该消息来自哪个交换机
     * @param routingKey 该消息的路由key
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println(message);
        System.out.println(replyCode + " " + replyText + " " + exchange);
    }
}

测试方式,不用启动消费者,然后再去 RabbitMQ 的管理界面中删除对应的交换机,然后在发送消息即可验证。

优化消息监控和到达队列的监控

创建 WatchMessageImpl,内容如下所示:

代码语言:java
AI代码解释
复制
/**
 * @author BNTang
 */
@Component
public class WatchMessageImpl implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    private void initRabbitTemplate() {
        this.rabbitTemplate.setConfirmCallback(this);
        this.rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 消息到达交换机的回调
     *
     * @param correlationData
     * @param ack             是否到达交换机
     * @param cause           如果没有接收成功,返回拒绝的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            System.out.println("消息正常到达交换机");
        } else {
            System.out.println("消息没有到达交换机,原因为:" + cause);
        }
    }

    /**
     * 当消息到达队列失败时,回调的方法,消息被退回了,我们可以把消息记录下来,分析错误的原因,以后重新发送,这样的话,消息就不会再丢失了
     *
     * @param message    消息体
     * @param replyCode  回退的响应码
     * @param replyText  响应文本
     * @param exchange   该消息来自哪个交换机
     * @param routingKey 该消息的路由key
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println(new String(message.getBody()) + "到达队列失败:" + replyCode + " " + replyText + " 交换机为:" + exchange + " 路由key:" + routingKey);
        // 处理重新发送的问题
    }
}

消息转换参数的问题

可以传自定义对象,但是自定义的对象必须序列化,在实际开发中一般使用 JSON 串去传自定义对象。

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
WinForm中使用XML文件存储用户配置及操作本地Config配置文件
大家都开发winform程序时候会大量用到配置App.config作为保持用户设置的基本信息,比如记住用户名,这样的弊端就是每个人一些个性化的设置每次更新程序的时候会被覆盖。
跟着阿笨一起玩NET
2018/09/19
3.2K0
Entity Framework——读写分离
1 实现 CustomDbContext扩展了DbContext,其构造函数带有形式参nameOrConnectionString,可以在使用CustomDbContext时指定数据库连接字符串。 DbContextFactory包含两个属性MasterDbContext和SlaveDbContext,MasterDbContext为主库上下文,SlaveDbContext为从库上下文。DbContextFactory还包含了一个方法:UpdateSlaves用于实现对SlaveDbContext的更新,因
甜橙很酸
2018/03/08
1.1K0
ConfigurationManager.ConnectionStrings 属性[通俗易懂]
转载于:https://www.cnblogs.com/herizai/p/7229898.html
全栈程序员站长
2022/08/31
5450
DotNet程序配置文件
    在实际的项目开发中,对于项目的相关信息的配置较多,在.NET项目中,我们较多的将程序的相关配置直接存储的.config文件中,例如web.config和app.config。   
彭泽0902
2018/01/04
1K0
asp.net 对xml文件的读写,添加,修改,删除操作
XmlNode xmldocSelect=xmlDoc.SelectSingleNode("user");
Java架构师必看
2021/03/22
1.7K0
C#操作XML方法汇总
一、简单介绍 using System.Xml; //初始化一个xml实例 XmlDocument xml=new XmlDocument(); //导入指定xml文件 xml.Load(path); xml.Load(HttpContext.Current.Server.MapPath("~/file/bookstore.xml")); //指定一个节点 XmlNode root=xml.SelectSingleNode("/root"); //获取节点下所有直接子节点 XmlNodeList
跟着阿笨一起玩NET
2018/09/18
3.2K0
GridView控件修改、删除示例(修改含有DropDownList控件)
GridView控件修改、删除例子,修改时含有DropDownList控件。 示例运行效果图:
Java架构师必看
2021/03/22
6580
C#三层架构实现WinForm连接Mysql显示数据库数据实例
首先创建数据库丨 学号 姓名 班级 QQ 微信 丨5列 三层架构,即包含 BLL,DAL,Model,DBHelper,Winform 必须 Mysql 包 using MySql.Data.MySq
骤雨重山
2022/01/17
2.8K0
web.config connectionStrings[通俗易懂]
web.config connectionStrings 数据库连接字符串的解释
全栈程序员站长
2022/08/31
1.4K0
c#用XmlDocument读取指定节点[通俗易懂]
大家好,又见面了,我是你们的朋友全栈君。 XML文档如下: <?xml version=”1.0″ standalone=”yes”?> < ItemData> < AccFirst> <Ta
全栈程序员站长
2022/09/06
1.9K0
ASP.NET2.0中用Gridview控件操作数据
在ASP.NET 2.0中,加入了许多新的功能和控件,相比asp.net 1.0/1.1,在各方面都有了很大的提高。其中,在数据控件方面,增加了不少控件,其中的Gridview控件功能十分强大。在本文中,将探讨Gridview控件中的一些功能特性和用法,如果各位读者对Gridview控件不大了解,可以通过《 使用ASP.NET 2.0中的Gridview控件》一文,来对Gridview控件有个初步的认识。
Java架构师必看
2021/03/22
1.5K0
java中的file是什么?[通俗易懂]
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说java中的file是什么?,希望能够帮助大家进步!!!
Java架构师必看
2022/01/17
1.1K0
java中的file是什么?[通俗易懂]
java中判断是否为数组[通俗易懂]
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说java中判断是否为数组,希望能够帮助大家进步!!!
Java架构师必看
2022/01/17
4.9K0
java中判断是否为数组[通俗易懂]
Visual Studio Package 插件开发之自动生成实体工具
  这一篇是VS插件基于Visual Studio SDK扩展开发的,可能有些朋友看到【生成实体】心里可能会暗想,T4模板都可以做了、动软不是已经做了么、不就是读库保存文件到指定路径么……
陈珙
2018/09/12
1.1K0
Visual Studio Package 插件开发之自动生成实体工具
Gridview导出到Excel,Gridview中的各类控件,Gridview中删除记录的处理
Asp.net 2.0中新增的gridview控件,是十分强大的数据展示控件,在前面的系列文章里,分别展示了其中很多的基本用法和技巧(详见< ASP.NET 2.0中Gridview控件高级技巧>)。在本文中,将继续探讨有关的技巧。
Java架构师必看
2021/03/22
2.8K0
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从类型系统开始讲起,我将通过跨语言操作这个例子来逐渐引入一系列.NET的相关概念,这主要包
小曾看世界
2018/08/03
4.8K0
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
相关推荐
WinForm中使用XML文件存储用户配置及操作本地Config配置文件
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • 概述
  • 创建项目
  • 监控消息到达交换机
  • 发送消息
  • 监控消息由交换机到队列里面
  • 优化消息监控和到达队列的监控
  • 消息转换参数的问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档