rabbitmq的消息应答

消费者完成一个任务可能需要一段时间,如果其中一个消费者处理一个长的任务并仅只完成
了部分突然它挂掉了,会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息,便立即将该消
息标记为删除。在这种情况下,突然有个消费者挂掉了,我们将丢失正在处理的消息。以及后续
发送给该消费这的消息,因为它无法接收到。
为了保证消息在发送过程中不丢失,rabbitmq 引入消息应答机制,消息应答就是: 消费者在接
收到消息并且处理该消息之后,告诉 rabbitmq 它已经处理了,rabbitmq 可以把该消息删除了。

消息应答的方法 

Channel.basicAck(用于肯定确认)

RabbitMQ 已知道该消息并且成功的处理消息,可以将其丢弃了

Channel.basicNack(用于否定确认)

Channel.basicReject(用于否定确认)

与 Channel.basicNack 相比少一个参数
不处理该消息了直接拒绝,可以将其丢弃了

自动应答 

消息发送后立即被认为已经传送成功,这种模式需要在 高吞吐量和数据传输安全性方面做权
,因为这种模式如果消息在接收到之前,消费者那边出现连接或者 channel 关闭,那么消息就丢
失了,当然另一方面这种模式消费者那边可以传递过载的消息, 没有对传递的消息数量进行限制
当然这样有可能使得消费者这边由于接收太多还来不及处理的消息,导致这些消息的积压,最终
使得内存耗尽,最终这些消费者线程被操作系统杀死, 所以这种模式仅适用在消费者可以高效并
以某种速率能够处理这些消息的情况下使用。默认消息采用的是自动应答.

手动应答

手动应答的好处是可以批量应答并且减少网络拥堵multiple 的 true 和 false 代表不同意思

true 代表批量应答 channel 上未应答的消息
比如说 channel 上有传送 tag 的消息 5,6,7,8 当前 tag 是 8 那么此时
5-8 的这些还未应答的消息都会被确认收到消息应答
false 同上面相比
只会应答 tag=8 的消息 5,6,7 这三个消息依然不会被确认收到消息应答

消费者1 

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class Worker01 {
     private static final String QUEUE_NAME="hello";

     public static void main(String[] args) throws Exception {
         Channel channel = RabbitMqUtils.getChannel();
         System.out.println("C1 等待接收消息处理时间较短");
         DeliverCallback deliverCallback=(consumerTag, delivery)->{
             String receivedMessage = new String(delivery.getBody());
             System.out.println("接收到消息:"+receivedMessage);
             try {
                 // 睡眠1秒
                 Thread.sleep(1000*1);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
             // 消息标记tag,2.false代表只应答接收到的那个传递的消息,true为应答所有消息包括传递过来的消息
             channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
         };
         CancelCallback cancelCallback=(consumerTag)->{
         System.out.println(consumerTag+"消费者取消消费接口回调逻辑");
         };
         System.out.println("C1 消费者启动等待消费......");
         boolean autoAck=false;
         channel.basicConsume(QUEUE_NAME,autoAck,deliverCallback,cancelCallback);
     }
}

 消费者2


import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

public class Worker02 {
    private static final String QUEUE_NAME="hello";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();
        System.out.println("C2 等待接收消息处理时间较长");
        DeliverCallback deliverCallback=(consumerTag, delivery)->{
            String receivedMessage = new String(delivery.getBody());
            System.out.println("接收到消息:"+receivedMessage);
            try {
                // 睡眠30秒
                Thread.sleep(1000*30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 消息标记tag,2.false代表只应答接收到的那个传递的消息,true为应答所有消息包括传递过来的消息
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        };
        CancelCallback cancelCallback=(consumerTag)->{
            System.out.println(consumerTag+"消费者取消消费接口回调逻辑");
        };
        System.out.println("C2 消费者启动等待消费......");
        boolean autoAck=false;
        channel.basicConsume(QUEUE_NAME,autoAck,deliverCallback,cancelCallback);
    }
}

生产者 

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Producer {
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws Exception {
                //创建一个连接工厂
                ConnectionFactory factory = new ConnectionFactory();
                factory.setHost("43.139.59.28");
                factory.setUsername("guest");
                factory.setPassword("guest");
                //channel 实现了自动 close 接口 自动关闭 不需要显示关闭
                try(Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
                /**
                * 生成一个队列
                * 1.队列名称
                * 2.队列里面的消息是否持久化 默认消息存储在内存中
                * 3.该队列是否只供一个消费者进行消费 是否进行共享 true 可以多个消费者消费
                * 4.是否自动删除 最后一个消费者端开连接以后 该队列是否自动删除 true 自动删除
                * 5.其他参数
                */
                channel.queueDeclare(QUEUE_NAME,false,false,false,null);
                String message="hello world!!!!";
                /**
                * 发送一个消息
                * 1.发送到那个交换机
                * 2.路由的 key 是哪个
                * 3.其他的参数信息
                * 4.发送消息的消息体
                */
                    for (int i = 0; i < 10; i++) {
                        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
                    }

                System.out.println("消息发送完毕");
           }
    }
}

结果

在发送者发送消息 ,发出消息之后的把 C2 消费者停掉,按理说该 C2 来处理该消息,但是
由于它处理时间较长,在还未处理完,也就是说 C2 还没有执行 ack 代码的时候,C2 被停掉了,
此时会看到消息被 C1 接收到了,说明消息  被重新入队,然后分配给能处理消息的 C1 处理了 

消息自动重新入队

如果消费者由于某些原因失去连接(其通道已关闭,连接已关闭或 TCP 连接丢失),导致消息
未发送 ACK 确认,RabbitMQ 将了解到消息未完全处理,并将对其重新排队。如果此时其他消费者
可以处理,它将很快将其重新分发给另一个消费者。这样,即使某个消费者偶尔死亡,也可以确
保不会丢失任何消息。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

jvm-类加载子系统

1.内存结构概述 类加载子系统负责从文件系统或网络中加载class文件&#xff0c;class文件在文件开头有特定的文件标识 ClassLoader只负责class文件的加载&#xff0c;至于它是否运行&#xff0c;则由Execution Engine决定 加载的类信息存放于一块称为方法区的内存空间&#xff…

SHELL 基础

echo 打印命令 &#xff1a; 显示字符串 [rootserver ~]# echo this is SHELL language this is SHELL language [rootserver ~]# echo this is SHELL language this is SHELL language [rootserver ~]# echo "this is SHELL language" this is SHELL language…

【java毕业设计】基于ssm+mysql+jsp的个性化影片推荐系统设计与实现(程序源码)-个性化影片推荐系统

基于ssmmysqljsp的个性化影片推荐系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于ssmmysqljsp的个性化影片推荐系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及论文的获取方式…

Bean 作用域、生命周期和Spring执行流程

文章目录 Bean作用域问题案例分析公共 BeanA 用户使用时修改B 用户使用时原因分析 作用域定义Bean 的6种作用域singletonprototyperequestsessionapplicationwebsocket 设置作用域 Spring 执行流程1、启动容器2、Bean 初始化3、注册Bean对象到容器中4、装配Bean属性 Bean 生命周…

redis 存储结构原理 1

关于 redis 相信大家都不陌生了&#xff0c;之前有从 0 -1 分享过 redis 的基本使用方式&#xff0c;用起来倒是都没有啥问题了&#xff0c;不过还是那句话&#xff0c;会应用之后&#xff0c;我们必须要究其原理&#xff0c;知其然知其所以然 今天我们来分享一下关于 redis 的…

“维度削减+逻辑回归”:如何使用PCA大幅提升乳腺癌的预测成功率?

一、引言 乳腺癌是女性中最常见的恶性肿瘤之一&#xff0c;也影响着全球范围内许多人们的健康。据世界卫生组织&#xff08;WHO&#xff09;的数据&#xff0c;乳腺癌是全球癌症发病率和死亡率最高的肿瘤之一&#xff0c;其对个体和社会的危害不可忽视。因此&#xff0c;早期乳…

Coremail参与编制|《信创安全发展蓝皮书——系统安全分册(2023年)》

信创安全发展蓝皮书 近日&#xff0c;Coremail参与编制的《信创安全发展蓝皮书—系统安全分册&#xff08;2023年&#xff09;》重磅发布。 此次信创安全发展蓝皮书由工业和信息化部电子第五研究所联合大数据协同安全技术国家工程研究中心重磅共同发布。 本次蓝皮书涵盖信创系…

使用el-tree实现自定义树结构样式

实现效果: 直接上代码: <template><div><div class"tops"><el-tree :default-expanded-keys"[1]" ref"myTree" :data"data" :props"defaultProps" node-click"handleNodeClick" highlight…

广州华锐互动:奶牛难产原因及救治VR仿真实训系统

奶牛难产是一种常见的疾病&#xff0c;对奶牛的健康和生产造成很大的影响。为了解决这一问题&#xff0c;许多奶牛养殖场开始采用VR仿真技术来培训奶牛兽医&#xff0c;帮助学生更好地理解奶牛养殖的实际过程&#xff0c;提高他们的实践能力的教学方式。 VR技术开发公司广州华锐…

二十二、策略模式

目录 1、项目需求2、传统方案解决鸭子问题的分析和代码实现3、传统方式实现存在的问题分析和解决方案4、策略模式基本介绍5、使用策略模式解决鸭子问题6、策略模式的注意事项和细节7、策略模式的使用场景 以具体项目来演示为什么需要策略模式&#xff0c;策略模式的优点&#x…

如何快速的合并多个PPT使之成为一个PPT?

如何快速的合并多个PPT使之成为一个PPT&#xff1f; 项目过程中&#xff0c;经常给客户汇报&#xff0c;经常做PPT&#xff0c;有时候&#xff0c;需要把之前的ppt内容整合到新的内容中&#xff0c;如何快速合并以及使用呢&#xff1f; 幻灯片&#xff08;PPT中&#xff09;点…

SpringBoot3集成Kafka

标签&#xff1a;Kafka3.Kafka-eagle3&#xff1b; 一、简介 Kafka是一个开源的分布式事件流平台&#xff0c;常被用于高性能数据管道、流分析、数据集成和关键任务应用&#xff0c;基于Zookeeper协调的处理平台&#xff0c;也是一种消息系统&#xff0c;具有更好的吞吐量、内…

Python入门【动态添加属性和方法、正则表达式概述、match函数的使用、常用匹配符、限定符 、限定符使用示例】(二十九)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

List Label Standard Reporting Edition Crack

List & Label Standard Reporting Edition Crack List&Label是适用于所有主要开发平台的报告解决方案&#xff0c;提供了强大的报告引擎、灵活的API和功能丰富的报告设计器。只需要几行代码就可以在桌面、web或云应用程序中嵌入List&Label。它允许您的应用程序用户…

Oracle字段长度不足位数补零

Oracle字段长度不足位数补零 有时候从数据库中取出的月份值是1&#xff0c;而不是01&#xff0c;该怎么办呢 SELECTLPAD( CODE_MONTH, 2, 0 ) FROMtb_cube_TY001 WHERECODE_BM_MEATYPE TY20 AND code_measure MYLX01 AND code_month <> ~ AND CODE_ENTITY 01A AND…

Spring框架中JavaBean的生命周期及单例模式与多列模式

Spring框架中JavaBean的生命周期及单例模式与多列模式 1. Spring框架中JavaBean的管理过程1.1 #定义Bean1.2 Bean的实例化1.3 属性注入1.4 初始化方法1.5 Bean的使用和引用1.6 销毁方法 2. 单例模式与原型模式在JavaBean管理中的应用1.在Spring管理JavaBean的过程中&#xff0c…

抖音短视频SEO矩阵系统源码开发

一、概述 抖音短视频SEO矩阵系统源码是一项综合技术&#xff0c;旨在帮助用户在抖音平台上创建并优化短视频内容。本文将详细介绍该系统的技术架构、核心代码、实现过程以及优化建议&#xff0c;以便读者更好地理解并应用这项技术。 二、技术架构 抖音短视频SEO矩阵系统采用前…

回归预测 | MATLAB实现TSO-BP金枪鱼群优化算法优化BP神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现TSO-BP金枪鱼群优化算法优化BP神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现TSO-BP金枪鱼群优化算法优化BP神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果…

机器学习|决策树:数学原理及代码解析

机器学习&#xff5c;决策树&#xff1a;数学原理及代码解析 决策树是一种常用的监督学习算法&#xff0c;适用于解决分类和回归问题。在本文中&#xff0c;我们将深入探讨决策树的数学原理&#xff0c;并提供 Python 示例代码帮助读者更好地理解和实现该算法。 决策树数学原…

3.若依前后端分离版开发用户自定义配置表格功能

一、背景 在项目上线测试的时候&#xff0c;关于同一个界面的表格&#xff0c;不同的用户会出现不同的字段排列需求&#xff0c;有些用户希望把A字段排在最前面&#xff0c;有些用户则希望A字段不显示。针对这种情况&#xff0c;开发一个表格自定义配置的功能&#xff0c;每个…