高级篇-rabbitmq的高级特性

news2025/3/4 11:59:50

 

 

1.消息可靠性

三种丢失的情形:

1.1  生产者确认机制 

 启动MQ

创建Queues: 

两种Callback:

1.ReturnCallback:全局callback 

 2.ComfirmCallback: 发送信息时候设置

 

 @Test
    public void testSendMessage2SimpleQueue() throws InterruptedException {
        // 1.准备消息
        String message = "hello, spring amqp!";
        // 2.准备CorrelationData
        // 2.1.消息ID
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        // 2.2.准备ConfirmCallback
        correlationData.getFuture().addCallback(result -> {
            // 判断结果
            if (result.isAck()) {
                // ACK
                log.debug("消息成功投递到交换机!消息ID: {}", correlationData.getId());
            } else {
                // NACK
                log.error("消息投递到交换机失败!消息ID:{}", correlationData.getId());
                // 重发消息
            }
        }, ex -> {
            // 记录日志
            log.error("消息发送失败!", ex);
            // 重发消息
        });
        // 3.发送消息
        rabbitTemplate.convertAndSend("amq.topic", "a.simple.test", message, correlationData);
    }

 执行成功:

 监控页面:

模拟失败:

 1.投递到交互机失败

2.投递到交换机了,但是没有进入队列 

 

1.2 消息持久化 

注意: 生产者确认只能保证数据放到队列当中,但是无法保证数据不丢失(比如所在的机器宕机了),
所以还需要保证数据的持久化

@Configuration
public class CommonConfig {
    @Bean
    public DirectExchange simpleDirect(){
        return new DirectExchange("simple.direct");
    }
    @Bean
    public Queue simpleQueue(){
        return QueueBuilder.durable("simple.queue").build();
    }
}
@Test
public void testDurableMessage() {
   // 1.准备消息 消息持久化
   Message message = MessageBuilder.withBody("hello, spring".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .build();
   // 2.发送消息
   rabbitTemplate.convertAndSend("simple.queue", message);
}

 注意:

    //交换机不传值默认就是持久化  
    //交换机、队列、消息默认都是持久化   
    @Bean
    public DirectExchange simpleDirect(){
        return new DirectExchange("simple.direct");
    }

    public AbstractExchange(String name) {
        this(name, true, false);
    }

  演示数据是否默认持久化: 

     重启mq:

 1. 交互机、队列、消息都做持久化

  2.消费者端关闭防止被消费

  3.重启mq后看队列中数据是否还在(是否持久化)

 1.3  消费者消息确认

生产者确认:能确定消息投递到队列
消息持久化:能避免MQ宕机造成的消息丢失
生产者确认和消息持久化能保证消息能投递到消费者,但是无法保证消息被消费者消费(比如投递消费者的
同时,消费者所在机器宕机了)

1.manual:不推荐 代码侵入
try{
  //业务逻辑
  ack
} catch(ex){
  nack
}
2.auto:推荐 spring全权完成,不需要手动写代码
3.none:不推荐 投递完成立马删除消息,是否成功都不管
@Slf4j
@Component
public class SpringRabbitListener { 
    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueue(String msg) {
        log.debug("消费者接收到simple.queue的消息:【" + msg + "】");
        //模拟出现异常情况
        System.out.println(1 / 0);
        log.info("消费者处理消息成功!");
    }
}

默认为none:抛出异常后消息立即被删除:

 修改为auto模式:

 

队列返回nack会再去发送信息: 

 

1.4 失败重试机制

 演示失败重试机制:

listener:
      simple:
        prefetch: 1
        acknowledge-mode: auto
        retry:
          enabled: true
          initial-interval: 1000
          multiplier: 3
          max-attempts: 4

 默认重试到达最大次数后消息就丢弃:

       但是对于一些比较重要不能丢弃的消息需要使用以下策略:     

推荐使用第三种方案:将失败的消息发送到失败的交换机和失败的队列中,后面可以告知管理员然后重新
人工去处理

 

@Configuration
public class ErrorMessageConfig {

    @Bean
    public DirectExchange errorMessageExchange(){
        return new DirectExchange("error.direct");
    }

    @Bean
    public Queue errorQueue(){
        return new Queue("error.queue");
    }

    @Bean
    public Binding errorMessageBinding(){
        return BindingBuilder.bind(errorQueue()).to(errorMessageExchange()).with("error");
    }

    @Bean
    public MessageRecoverer republishMessageRecoverer(RabbitTemplate rabbitTemplate){
        return new RepublishMessageRecoverer(rabbitTemplate, "error.direct", "error");
    }
}

 演示:

发送消息:

 

 面试题:最后一分钟的总结

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/104321.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第八章练习题-3

目录 第十三题 题目 Student类 Teacher类 main类 老师的代码 Student类 Teacher类 main类 第七问:定义多态数组 main类 运行结果 问题 原因 解决办法 老师代码:main类 结果 第八问 运行结果 第十四题 第十五题 题目 方法的多态…

HFSS使用经验三

目录 一、如何量取HFSS某一点的空间位置 二、如何快速的切换视图 三、HFSS中绘制圆柱体 四、如何修改HFSS的仿真线程数量 五、HFSS中如何选取挖空的面 六、HFSS中如何实现参数扫描 一、如何量取HFSS某一点的空间位置 右击可以点击Measure按键 鼠标放到特殊点&#xff0c…

2023年申请发明专利的重要性和注意问题。

随着对知识产权意思的逐步提高,企业对知识产权越来越关心。知识产权包括专利权、商标权和著作权。专利包含发明专利专利、实用新型专利、外观设计专利。其中发明专利的申请难度最大,含金量最高。根据小编申请发明专利方面20年的经验,简单介绍…

【Windows|WSL|Ubuntu|VSCode】流程记录|坑点模糊回忆

无限踩坑,悲惨回忆,又似乎毫无意义? 1.安装WSL 官方文档:Install WSL | Microsoft Learn 简单来说,管理员身份运行PowerShell wsl --install 通常需要wsl2,得益于其优势,通过 PowerShell w…

用ERP系统做数据管理对企业有什么好处?

ERP系统数据管理解决方案是以业务为主导的工具,为所有的业务流程和操作创建一个单一的主记录,包括来自各种内部和外部应用和来源的人员和系统。 大多数企业采用不同的系统,包含客户、产品、销售、交易等信息数据存储在许多不同的地方&#…

葵花宝典之C语言冷知识(二)

目录 🚓(一)图形的打印 🚙判断类型 🚌逻辑简单易找规律型。 🚌存在坐标规律的图案打印 🚓(二)中值的表达形式 🚙(xy)/2 表达错误的原因 🚙有符号数…

Python编程课程好学吗?能学会吗?

Python编程课程好学吗?能学会吗?Python是一种计算机程序设计语言,一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加越来越多被用于独立的大型项目的开发。 编程…

mvn和npm的那些事

1 mvn简介 mvn就好比java中的maven,用于管理包版本,mvn用于管理node版本,而npm来源于node中,比如用于拉取仓库中的依赖包,在构建使用项目时可以选择指定的版本,从而避免编译出错运行失败等问题 Node.js17或更高版本中出现Error: error:0308010C:digital envelope routine…

CSDN如何使用Markdown编辑器

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

Pytest自动化测试 - 完美结合Allure

简介 Allure Framework是一种灵活的、轻量级、多语言测试报告工具。 不仅可以以简洁的网络报告形式非常简洁地显示已测试的内容, 而且还允许参与开发过程的每个人从日常执行中提取最大程度的有用信息和测试。 从开发/测试的角度来看: Allure报告可以…

四大蓝牙天线设计方式

https://www.elecfans.com/d/686538.html 一直以来,无论是智能手机,还是笔记本电脑,亦或是平板电脑,蓝牙都是智能设备的标配。随着移动互联网的发展,现在涌现出大量的智能可穿戴设备,而支撑这些应用的发展不…

Spring AOP源码解析——专治你不会看源码的坏毛病!

虽然现在大厂内卷现象泛滥,而且996的传统依旧肆虐。但没有哪位程序员能架得住互联网大厂的高薪职位诱惑。特别是我还有一位在阿里工作7年多的老表,在其耳旁风之下,不断将大厂描绘的美丽风景刻画在我脑海中,也让我一直有着想进大厂…

架构设计(八):数据库的水平扩展和垂直扩展

架构设计(八):数据库的水平扩展和垂直扩展 作者:Grey 原文地址: 博客园:架构设计(八):数据库的水平扩展和垂直扩展 CSDN:架构设计(八&#xf…

Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))

3 Redis列表(List) 3.1 简介 单键多值 Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 它的底层实际是个双向链表,对两端的操作性能很高&#x…

组件技术--设计--MVC模式+DAO+MySQL+jsp+servlet 简单的购物车案例

MVC模式DAOMySQLjspservlet 简单的购物车案例题外话购物车案例需求核心系统组成Javaweb项目框架基本思想核心代码DaoBookDaolistenerSessionListenerservletAddServletInitServletRemoveServletvoBook.jspbuyForm.jspshowAllBook.jspshowCart.jsptargetpom.xmlWEB-INFweb.xmlli…

python绘图——坐标轴

1. 2D坐标轴 1.1 绘制简单的曲线 import matplotlib.pyplot as plt import numpy as np xnp.linspace(-1,1,50)#-1到1中画50个点 yx**2 plt.plot(x,y,colorgreen) plt.tick_params(axisx,colorsblue) plt.tick_params(axisy,colorsred) plt.show()作图: 1.2 坐标…

游戏开发 LinkedList

inkedList底层是双向链表,一个节点挂着一个节点LinkedList不需要设定长度,不需要扩容LinkedList 的优缺点 优点 ① 往里面插入一些元素的时候不需要像ArrayList数组那样需要挪动大量的元素了,直接在链表里加入一个节点就可以了 ② 如果要不断…

【数据结构】LinkedList与双向链表

目录 一、认识集合类LinkedList 1、认识 2、构造方法 二、实现双向非循环链表 1、准备 2、方法的实现 1.遍历 2.有效节点个数 3.是否包含key 4.清空链表 5.头插法 6.尾插法 7.指定位置插入 8.删除第一次出现的key 9.删除所有的key 一、认识集合类LinkedList 1、认…

第01讲:Linux系统下Redis的安装及配置

本文所安装的Redis版本为5.0.4,请自行到官网下载,或者私信博主 前言:什么是Redis 介绍Redis之前,先了解下NoSQL (Not only SQL)不仅仅是SQL属于非关系型数据库;Redis就属于非关系型数据库传统的…

【AJAX】入门AJAX

入门AJAXAJAX概述AJAX的使用XMLHttpRequest创建XMLHttpRequest对象XMLHttpRequest对象的常用方法XMLHttpRequest对象的常用属性使用AJAX POST请求实现‘判断用户名’案例实现步骤模拟数据库表单前端代码后端程序效果展示AJAX概述 什么是AJAX? AJAX全称(…