《RabbitMQ篇》消息应答和发布确认

消息应答

消息应答机制:消费者接收信息并处理完之后,告诉rabbitmq该信息已经处理,rabbitmq可以把该信息删除了.

消息自动重新入队:如果处理某个消息的消费者异常关闭了,没有发送ACK确认,rabbitmq会将其重新入队,分发给其他消费者处理。

自动应答

消息发送后即被认为传送成功。该模式弊端,消费者不断的接收消息,如果处理不及时,导致内存耗尽,系统杀死消费者进程。所以适用于消费者可以高效处理信息的情况下。

手动应答:

Channel.basicAck(long deliveryTag, boolean multiple):

确认一条或多条收到的消息。对于经过确认的消息,RabbitMQ 认为该消息成功的处理,可以将其丢弃了。

在手动应答情况下,如果消费者没有关闭,但就是不发送ACK确认,这条消息就会一直在MQ中显示unacked,不会重新分发给其他消费者。

deliveryTag:对应消息的标识。

multiple:如果为True,则应用多消息。

multiple该参数用于开启批量应答:比如说 channel 上有传送 tag 的消息 5,6,7,8 当前 tag 是 8 那么此时 5-8 的还未应答的消息都会被确认收到消息应答。

Channel.basicNack(long deliveryTag, boolean multiple, boolean requeue):

拒绝一条或多条收到的消息。

deliveryTag:对应消息的标识。

multiple:如果为True,则应用多消息。

requeue:如果为True,拒绝的消息将会重新加入队列

重新入队的消息会分发给其他消费者,不重新入队的消息将会丢失/死信。

Channel.basicReject(long deliveryTag, boolean requeue):

拒绝一条消息。与 Channel.basicNack 相比少一个参数Multiple。

发布确认

生产者把消息发送到MQ后,需要MQ返回一个ACK给生产者,这样生产者才知道自己的消息成功发出去了。

实现过程:生产者将信道设置成confirm模式,所有在该信道的消息都会被指派一个唯一的id,消息到达匹配的队列后,broker发送一个确认给生产者,这样生产者就知道消息已经发布到MQ了

RabbitMQ默认没有开启发布确认模式的,需要使用Channel.confirmSelect() 开启发布确认。

Channel.waitForCinfirms():等待Broker确认或拒绝自上次调用以来发布的所有消息。

单个发布确认

单个确认发布:发布一个确认一个,才能接着发第二个。

优缺点:可以确认哪个消息失败,适用于吞吐量不大的程序。

public class ConfirmMessage {

    //消息的个数
    public static final int MESSAGE_COUNT = 1000; 

    public static void main(String[] args) throws Exception {
        publishMessageIndividually();//发布1000个单独确认消息,耗时:546ms
    }
    public static void publishMessageIndividually() throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        //队列的声明
        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName,false,true,false,null);
    
        //开启发布确认
        channel.confirmSelect();
        //开始时间
        long begin = System.currentTimeMillis();
    
        //批量发消息
        for (int i = 1; i <= MESSAGE_COUNT; i++) {
            String message = i+"";
            channel.basicPublish("",queueName,null,message.getBytes());
            //单个确认
            boolean flag = channel.waitForConfirms();
            if(flag){
                // TODO:消息发送成功的处理逻辑
            } else {
                // TODO: 消息发送失败的处理逻辑
            }
        }
        //结束时间
        long end = System.currentTimeMillis();
        System.out.println("发布"+MESSAGE_COUNT+"个单独确认消息,耗时:"+(end-begin)+"ms");
    }
}

批量发布确认

批量发布确认:以批次发布,一批次可以有很多消息,待批次发布完,才确认。

优缺点:速度比单个快,但是不能确认哪个消息失败。

public class ConfirmMessage {

    //消息的个数
    public static final int MESSAGE_COUNT = 1000; 

    public static void main(String[] args) throws Exception {
        publishMessageBatch(); //发布1000个批量确认消息,耗时:117ms
    }
    public static void publishMessageBatch() throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        //队列的声明
        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName,false,true,false,null);
        //开启发布确认
        channel.confirmSelect();
        //开始时间
        long begin = System.currentTimeMillis();
    
        int batchSize = 10;
    
        //批量发消息
        for (int i = 1; i <= MESSAGE_COUNT; i++) {
            String message = i+"";
            channel.basicPublish("",queueName,null,message.getBytes());
            //批量确认
            if(i % batchSize == 0) {
                boolean flag = channel.waitForConfirms();
                if(flag) {
                    // TODO:消息发送成功的处理逻辑
                } else {
                    // TODO: 消息发送失败的处理逻辑
                }
            }
        }
    
        //结束时间
        long end = System.currentTimeMillis();
        System.out.println("发布"+MESSAGE_COUNT+"个批量确认消息,耗时:"+(end-begin)+"ms");
    
    }
}

异步发布确认

异步确认发布:每个信息都有自己的标识,一直发布即可,发布成功与否,都会有回调信息。

优缺点:最快,又能确认哪个消息发布失败。

public class ConfirmMessage {

    //消息的个数
    public static final int MESSAGE_COUNT = 1000;

    public static void main(String[] args) throws Exception {
        publishMessageAsync(); //发布1000个异步确认消息,耗时:61ms
    }
    public static void publishMessageAsync() throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        //队列的声明
        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName,false,true,false,null);
        //开启发布确认
        channel.confirmSelect();
        //开始时间
        long begin = System.currentTimeMillis();

        //异步确认
        ConfirmCallback confirmAckCallback = (deliveryTag, multiple) -> {
            // TODO:消息发送成功的处理逻辑
        };
        ConfirmCallback confirmNackCallback = (deliveryTag, multiple) -> {
            // TODO: 消息发送失败的处理逻辑
        };
        channel.addConfirmListener(confirmAckCallback, confirmNackCallback);

        //批量发消息
        for (int i = 1; i <= MESSAGE_COUNT; i++) {
            String message = i+"";
            channel.basicPublish("",queueName,null,message.getBytes());
        }

        //结束时间
        long end = System.currentTimeMillis();
        System.out.println("发布"+MESSAGE_COUNT+"个异步确认消息,耗时:"+(end-begin)+"ms");
    }
}

消息应答和发布确认的区别

消息应答属于消费者,消费完消息告诉MQ已经消费成功。

发布确认属于生产者,生产消息发送到MQ,MQ告诉生产者已经收到消息。

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

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

相关文章

金九银十软件测试面试题(800道)

今年你的目标是拿下大厂offer&#xff1f;还是多少万年薪&#xff1f;其实这些都离不开日积月累的过程。 为此我特意整理出一份&#xff08;超详细笔记/面试题&#xff09;它几乎涵盖了所有的测试开发技术栈&#xff0c;非常珍贵&#xff0c;人手一份 肝完进大厂 妥妥的&#…

postgresql 安装

一、下载 PostgreSQL: File Browser 下载地址 PostgreSQL: File Browser 上传到服务器,并解压 二、安装依赖 yum install -y perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel 创建postgresql 和目录 useradd …

Java-基础

1. 导入模块不能纯粹的复制粘贴&#xff0c;要从new里导入&#xff0c;因为前者建立不了关联 2. 数组 String[] name{"张三","李四","王五"};int[] numsnew int[]{1,2,3};//二维String[][] names{{"张三","李四"},{"…

39 C 语言枚举类型、枚举常量、枚举变量、枚举的遍历、枚举数组、枚举与 switch

目录 1 什么是枚举 2 定义枚举类型 2.1 语法格式 2.2 枚举元素的特点 2.3 案例演示 3 枚举变量 3.1 什么是枚举变量 3.2 定义枚举变量的多种方式 3.3 案例演示 1&#xff1a;标准版枚举类型 3.4 案例演示 2&#xff1a;简化版枚举类型 3.5 案例演示 3&#xff1a;匿…

uniapp学习(005-2 详解Part.2)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第41p-第p51的内容 文章目录 mainifest.json文件配置获取微信小程序appid注册微信小程序微信小程序控制台图形界…

22. 括号生成【回溯】

文章目录 22. 括号生成解题思路Go代码 22. 括号生成 22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))",&quo…

node.js服务器基础

node.js的事件循环 node.js是基于事件驱动的&#xff0c;通常在代码中注册想要等待的事件&#xff0c;设定好回调函数&#xff0c;当事件触发的时候就会调用回调函数。如果node.js没有要处理的事件了&#xff0c;那整个就结束了;事件里面可以继续插入事件&#xff0c;如果有事…

手撕数据结构 —— 带头双向循环链表(C语言讲解)

目录 0.前言 1.什么是带头双向循环链表 理解带头 ​编辑 理解双向 理解循环 2.带头双向循环链表的实现 List.h文件中接口总览 具体实现 结点的定义 申请结点 初始化 打印链表 尾插 尾删 头插 头删 ​编辑​编辑 获取大小 查找 在指定位置前插入 ​编辑…

数据结构--线性表双向链表的实现

目录 思路设计 总体思维导图 插入部分 头插法尾插法 任意位置插入 删除部分 头结点 尾节点 中间节点 只有头结点且删除的就是头结点 ​编辑 清空链表部分 遍历清空链表的所有节点 不遍历清空 各部分代码 Main部分 MyListedList部分 IndexOutOfException部分 …

YOLO11改进 | 注意力机制 | 结合静态和动态上下文信息的注意力机制

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 上下文Transformer&#xff08;CoT&…

WPF中的布局

布局原则 1、不显式设置元素大小。 2、不使用绝对定位。 元素应该根据容器的内容来进行排列。绝对定位在开发前期会带来一些便捷&#xff0c;但扩展性比较差。一旦显示器尺寸或分辨率发生改变&#xff0c;界面的显示效果可能会达不到预期的效果。 3、布局容器可以嵌套使用 常…

【Axure原型分享】标签管理列表

今天和大家分享通过标签管理列表的原型模板&#xff0c;包括增删改查搜索筛选排序分页翻页等效果&#xff0c;这个模板是用中继器制作的&#xff0c;所以使用也很方便&#xff0c;初始数据我们只要在中继器表格里填写即可&#xff0c;具体效果可以观看下方视频或者打开预览地址…

【经管】上市公司供应链金融数据(1990-2023年)

上市公司供应链金融是指上市公司利用其产业链核心地位&#xff0c;通过整合金融资源&#xff0c;为供应链上下游企业提供包括融资、结算、风险管理等在内的综合金融服务。为了衡量上市公司的供应链金融水平&#xff0c;参考周兰等&#xff08;2022&#xff09;的研究方法&#…

【C++入门篇 - 3】:从C到C++第二篇

文章目录 从C到C第二篇new和delete命名空间命名空间的访问 cin和coutstring的基本使用 从C到C第二篇 new和delete 在C中用来向系统申请堆区的内存空间 New的作用相当于C语言中的malloc Delete的作用相当于C语言中的free 注意&#xff1a;在C语言中&#xff0c;如果内存不够…

IBM Flex System服务器硬件监控指标解读

随着企业IT架构的日益复杂&#xff0c;服务器的稳定运行对于保障业务连续性至关重要。IBM Flex System作为一款模块化、可扩展的服务器解决方案&#xff0c;广泛应用于各种企业级环境中。为了确保IBM Flex System服务器的稳定运行&#xff0c;监控易作为一款专业的IT基础设施监…

git维护【.gitignore文件】

在工程下添加 .gitignore 文件【git忽略文件】 *.class .idea *.iml *.jar /*/target/更多&#xff1a; # Compiled class file *.class# Log file *.log *.imi *.lst# BlueJ files *.ctxt# Mobile Tools for Java (J2ME) .mtj.tmp/# Package Files # *.jar *.war *.nar *.ea…

【MySQL 保姆级教学】数据库基础(重点)(2)

目录 1. 什么是数据库1.1 数据库的定义1.2 mysql 和 mysqld1.3 文件和数据库 2. 数据库的分类3. 连接数据库3.1 数据库的安装3.2 连接服务器&#xff08;数据库&#xff09;3.3 服务器 数据库 表 三者的关系 4. 数据库-表 和目录-文件 的关系5. MySQL 框架6. SQL 分类7. 储存引…

DDoS攻击快速增长,如何在抗ddos防护中获得主动?

当下DDoS攻击规模不断突破上限。前段时间&#xff0c;中国首款3A《黑神话&#xff1a;悟空》也在一夜之内遭受到28万次攻击DDoS攻击&#xff0c;严重影响到全球玩家的游戏体验。Gcore发布的数据也显示了 DDoS攻击令人担忧的趋势&#xff0c;尤其是峰值攻击已增加到了令人震惊的…

CNN-GRU时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测

时序预测 | MATLAB实CNN-GRU卷积门控循环单元时间序列预测 目录 时序预测 | MATLAB实CNN-GRU卷积门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 本次运行测试环境MATLAB2020b 提出了一种基于卷积神经网络(Convolutional Neural Network…

生成式专题的第一节课---GAN图像生成

一、GAN的起源与发展 1.GAN的起源 GAN &#xff08;生成式对抗网络&#xff09;诞生于 2014 年&#xff0c;由 Ian Goodfellow 提出&#xff0c;是用于生成数据的深度学习模型&#xff0c;创新点是对抗性训练&#xff0c;即生成器与判别器的竞争关系&#xff0c;为图像生成、…