RabbitMQ之消费者ACK 功能

ops/2024/9/23 10:29:42/

什么是消费者ACK?
简单说就是 消息确认机制 mq要保证消息能可靠的达到消费者。消费者在消费是是可以指定autoAck参数(自动/手动)的方式告诉mq自己是否确认收到消息。
当 autoAck 参数为 false 时, 队列中的消息分成了两部分: 一部分是等待投递给消费者的消息;一部分是已经投递给消费者,但是还没有收到消费者确认信号的消息。 若 RabbitMQ 服务器端一直没有收到消费者的确认信号,并且消费此消息的消费者已经断开连接, 则服务器端会安排该消息重新进入队列,等待投递给下一个消费者(也可能还是原来的那个消费者)。
如下图
在这里插入图片描述
可以看到当前队列中的 “Ready” 状态和 “Unacked” 状态的消息数,分别对应等待投递给消费者的消息数和已经投递给消费者但是未收到确认信号的消息数。
上述说明 消息需要确认后消息将会被释放掉 从磁盘/内存中。
所以消息确认分类有两大类 如下图
在这里插入图片描述
由上图可知
有发送方确认、接收方确认。
注意:
其中发送方确认又分为:生产者到交换器到确认、交换器到队列的确认
本节主要介绍 消费者消息确认
方式一,自动确认。
方式二,手动确认。
对于自动确认的方式,RabbitMQ Broker 只要将消息写入到 TCP Socket 中成功,就认为该消息投递成功,而无需 Consumer 手动确认。

对于手动确认的方式,RabbitMQ Broker 将消息发送给 Consumer 之后,由 Consumer 手动确认之后,才任务消息投递成功。

实际场景下,因为自动确认存在可能丢失消息的情况,所以在对可靠性有要求的场景下,我们基本采用手动确认。当然,如果允许消息有一定的丢失,对性能有更高的产经下,我们可以考虑采用自动确认。

进行实战演练
yml配置类

spring:rabbitmq:#host为一般模式 若集群模式 将key换成addresses的形式host: 192.168.9.104port: 5672#账号密码自行替换username: adminpassword: admin# 以下手动提交消息listener:simple:acknowledge-mode: manualdirect:acknowledge-mode: manual

以上ackoneledge-mode的值有如下:
NONE 对应 Consumer 的自动确认
MANUAL 对应 Consumer 的手动确认,由开发者在消费逻辑中,手动进行确认。
AUTO 对应 Consumer 的手动确认,在消费消息完成(包括正常返回、和抛出异常)后,由 Spring-AMQP 框架来“自动”进行确认。
以下为逻辑代码演示

================Direct Exchange 配置
@Configuration
public class DirectExchangeConfiguration {/*** 创建一个 Queue** @return Queue*/@Beanpublic Queue queue05() {// Queue:名字 | durable: 是否持久化 | exclusive: 是否排它 | autoDelete: 是否自动删除return new Queue(Message05.QUEUE,true,false,false);}/*** 创建 Direct Exchange** @return DirectExchange*/@Beanpublic DirectExchange exchange05() {// name: 交换机名字 | durable: 是否持久化 | exclusive: 是否排它return new DirectExchange(Message05.EXCHANGE,true,false);}/*** 创建 Binding* Exchange:Message05.EXCHANGE* Routing key:Message05.ROUTING_KEY* Queue:Message05.QUEUE** @return Binding*/@Beanpublic Binding binding05() {return BindingBuilder.bind(queue05()).to(exchange05()).with(Message05.ROUTING_KEY);}
=======================================》 direct 类型的消息对象
@Data
public class Message05 implements Serializable {public static final String QUEUE = "QUEUE_05";public static final String EXCHANGE = "EXCHANGE_05";public static final String ROUTING_KEY = "ROUTING_KEY_05";private String id;
}
=======================================》 生产者逻辑
@Component
public class Producer05 {@Resourceprivate RabbitTemplate rabbitTemplate;public void syncSend(String id) {// 创建 Message05 消息Message05 message = new Message05();message.setId(id);// 同步发送消息rabbitTemplate.convertAndSend(Message05.EXCHANGE, Message05.ROUTING_KEY, message);}
}
=======================================》 消费者逻辑
@Component
@RabbitListener(queues = Message05.QUEUE)
@Slf4j
public class Consumer05 {/***  ack 模式 ,* 这里需要和 application.yml 中的 acknowledge-mode: manual  对应一起使用*/@RabbitHandlerpublic void onMessageAck(Message05 message01, Message message, Channel channel) throws IOException {try {log.info("[Consumer05 onMessageAck][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message01);//  如果手动ACK,消息会被监听消费,但是消息在队列中依旧存在,如果 未配置 acknowledge-mode 默认是会在消费完毕后自动ACK掉long deliveryTag = message.getMessageProperties().getDeliveryTag();// 取当前时间,达到一个随机效果,测试的话可以多跑几次试试if (System.currentTimeMillis() % 2 == 1) {// 通知 MQ 消息已被成功消费,可以ACK了// 第二个参数 multiple ,用于批量确认消息,为了减少网络流量,手动确认可以被批处。// 1. 当 multiple 为 true 时,则可以一次性确认 deliveryTag 小于等于传入值的所有消息// 2. 当 multiple 为 false 时,则只确认当前 deliveryTag 对应的消息channel.basicAck(deliveryTag, false);log.info("[Consumer05 onMessageAck][正常ack:{}]", message01);} else {log.info("[Consumer05 onMessageAck][未ack:{}]", message01);throw new RuntimeException("手动异常");}} catch (Exception e) {// 处理失败,重新压入MQchannel.basicRecover();log.info("[Consumer05 onMessageAck][消息重新压入MQ:{}]", message01);}}
=======================================》测试类@Testvoid syncSend() {String id = UUID.randomUUID().toString();producer05.syncSend(id);log.info("[test producer05 syncSend][id:{}] 发送成功", id);TimeUnit.SECONDS.sleep(2);}

以上的是消费者ACK实现的代码 若不了解rabbitmq的基本使用 建议先看看我前面对应的文章 文章链接:点我—>let’s go
若需完整代码 可识别二维码后 给您发代码。
在这里插入图片描述


http://www.ppmy.cn/ops/32715.html

相关文章

自动驾驶 | 仿真测试-HiL测试全解析

1.HiL 的定义 HiL(Hardware-in-the-Loop)硬件在环是计算机专业术语,也即是硬件在回路。通过使用 “硬件在环”(HiL) ,可以显著降低开发时间和成本。在过去,开发电气机械元件或系统时,使用计算机仿真和实际的实验就已经…

uni-app scroll-view隐藏滚动条的小细节 兼容主流浏览器

开端 想写个横向滚动的列表适配浏览器,主要就是隐藏一下滚动条在手机上美观一点。 但是使用uni-app官方文档建议的::-webkit-scrollbar在目标标签时发现没生效。 .scroll-view_H::-webkit-scrollbar{display: none; }解决 F12看了一下,原来编译到浏览…

力扣每日一题105:从前序与中序序列构造二叉树

题目 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null,1…

胖喵拼音输入法 (pmim-ibus) 安装说明

为了方便胖喵拼音的用户, 把这个文档发布到方便阅读的地方. pmim-ibus 安装 需要 flatpak: https://flatpak.org/setup/ 国内 flathub 镜像: https://mirror.sjtu.edu.cn/docs/flathub > flatpak install flathub io.github.fm_elpac.pmim_ibus安装之后的配置如下: 目录:…

RabbitMQ(Docker 单机部署)

序言 本文给大家介绍如何使用 Docker 单机部署 RabbitMQ 并与 SpringBoot 整合使用。 一、部署流程 拉取镜像 docker pull rabbitmq:3-management镜像拉取成功之后使用下面命令启动 rabbitmq 容器 docker run \# 指定用户名-e RABBITMQ_DEFAULT_USERusername \# 指定密码-e R…

翔云优配恒生指数涨1.85%、恒生科技指数涨3.74% 小鹏汽车涨超8%

5月3日港股开盘,恒生指数涨1.85%,报18543.3点,恒生科技指数涨3.74%,报4009.96点,国企指数涨2.23%,报6580.81点, 翔云优配是一家领先的在线投资平台,提供全球范围内的股票、期货、基金等交易服务…

anaconda、cuda、tensorflow、pycharm环境安装

anaconda、cuda、tensorflow、pycharm环境安装 anaconda安装 anaconda官方下载地址 本文使用的是基于python3.9的anaconda 接下来跟着步骤安装: 检验conda是否成功安装 安装CUDA和cuDNN 提醒,CUDA和cuDNN两者必须版本对应,否者将会出错…

Oracle 19c OCM考试难度如何?

许多人对 Oracle 19c OCM 的考试规则并不熟悉,本文将详细介绍考证所需条件以及具体要求,以帮助大家更顺利地完成考试流程。 首先,考生需具备相匹配的同级别 OCP 证书,如已获得 10g/11g/12c 证书者,则须先完成 083 升级…