10.发布确认

news2024/11/14 14:56:27

解决消息不丢失的一个重要环节。

前面说过消息持久化,可能出现一种情况就是:

尽管它告诉rabbitmq将消息保存到磁盘,但是依然存在当消息刚准备存储到磁盘的时候,但是还没有存储完,消息还在缓存的一个间隔点。此时消息并没有真正的写入磁盘。持久性保证并不强。

发布确认:

就是当消息真正保存到磁盘上的时候,mq要跟生产者说一声真的将消息保存到磁盘上了。

第一步:开启发布确认的方法

发布确认默认是关闭的。

生产者的信道上开启

//开启发布确认
channel.confirmSelect();

发布的类型:

单个确认发布

同步确认发布方式,缺点:发布速度特别慢。

/**
     * 单个确认,同步
     * @throws IOException
     */
    public static void confirmSingle() throws IOException, InterruptedException {
        Channel channel = RabbitMQUtil.getChannel();
        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName, true, false, false, null);
        //开启发布确认
        channel.confirmSelect();
        long start = System.currentTimeMillis();
        for (int i = 0; i < MESSAGE_COUNT; i++) {
            String message = i + "";
            channel.basicPublish("", queueName, null, message.getBytes());
            //单个消息发送后,马上进行确认
            boolean flag = channel.waitForConfirms();
            if(flag) {
                System.out.println("消息发送成功");
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("发布"+MESSAGE_COUNT+"条消息,单个消息确认消耗时间为:"+(end - start)+"ms");
    }
// 发布1000条消息,单个消息确认消耗时间为:851ms

批量确认发布

比单个确认的速度快,但是缺点是当发生故障导致发布出现问题时,不知道是那个消息出现了问题,这种方案也是同步的,一样阻塞消息的发布。

public static void batchConfirm() throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName, true, false, false, null);
        //开启发布确认
        channel.confirmSelect();
        long start = System.currentTimeMillis();
        int batch = 100;
        for (int i = 1; i <= MESSAGE_COUNT; i++) {
            String message = i + "";
            channel.basicPublish("", queueName, null, message.getBytes());
            //批量处理消息,每一百条消息进行一次确认
            if(i % batch == 0) {
                boolean flag = channel.waitForConfirms();
                if(flag) {
                    System.out.println("消息发送成功");
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("发布"+MESSAGE_COUNT+"条消息,批量消息确认(每100条确认一次)消耗时间为:"+(end - start)+"ms");
    }

发布1000条消息,批量消息确认(每100条确认一次)消耗时间为:132ms

异步确认发布

逻辑上比前两个要复杂,但是性能比较高。无论是可靠性和效率都没得说。利用回调函数来达到消息的可靠性传递的。

broker会异步通知。

 /**
     * 异步确认发布
     * @throws Exception
     */
    public static void asyncConfirm() throws Exception {
        Channel channel = RabbitMQUtil.getChannel();
        String queueName = UUID.randomUUID().toString();
        channel.queueDeclare(queueName, true, false, false, null);
        //开启发布确认
        channel.confirmSelect();
        //准备一个安全有序的一个哈希表,适用于高并发情况下
        //1.轻松将序号和消息进行关联
        //2.轻松批量删除条目,只要给到序号
        //3.支持高并发多线程
        ConcurrentSkipListMap<Long, String> concurrentSkipListMap = new ConcurrentSkipListMap<>();


        long start = System.currentTimeMillis();

        //消息确认成功回调函数
        //第一个参数:消息的标记
        //第二个参数:是否为批量
        ConfirmCallback ackCallback = (deliveryTag, multiple) -> {
            //删除掉已经确认的消息,剩下的就是未确认的消息
            if(multiple) { //批量确认
                ConcurrentNavigableMap<Long, String> concurrentNavigableMap = concurrentSkipListMap.headMap(deliveryTag);
                concurrentNavigableMap.clear();//全部删除
            }else {//单个
                concurrentSkipListMap.remove(deliveryTag);
            }
            System.out.println("确认的消息:" + deliveryTag);
        };
        //消息确认失败回调函数
        ConfirmCallback nackCallBack = (deliveryTag, multiple) -> {
            //打印一下未确认消息有哪些
            String message = concurrentSkipListMap.get(deliveryTag);
            System.out.println("未确认的消息:" + message + "消息tag=" + deliveryTag);
        };
        //准备消息的监听器,监听哪些消息成功了,哪些消息失败了
        channel.addConfirmListener(ackCallback, nackCallBack);

        for (int i = 0; i < MESSAGE_COUNT; i++) {
            String message = i + "";
            channel.basicPublish("", queueName, null, message.getBytes());
            //记录下所有要发送的消息,消息的总和
            concurrentSkipListMap.put(channel.getNextPublishSeqNo(), message);
        }

        long end = System.currentTimeMillis();

        System.out.println("发布"+MESSAGE_COUNT+"条消息,批量异步消息确认消耗时间为:"+(end - start)+"ms");
    }

发布1000条消息,批量异步消息确认消耗时间为:39ms

如何处理异步未确认消息

最好的解决方案就是把未确认的消息放到一个基于内存的能被发布线程访问的队列,比如说用ConcurrentLinkedQueue这个队列,在confirm callbacks发布线程之间进行消息的传递

两个线程:一个线程负责监听,另一个线程负责发送消息。

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

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

相关文章

充电桩--交流充电桩硬件原理以及竞品方案

聚焦光伏领域、深耕储能市场、探究充电技术 微信公众号 小Q下午茶 聚焦光伏领域&#xff0c;深耕储能市场&#xff0c;探究充电技术 47篇原创内容 公众号 一、交流充电桩系统介绍 为了实现能源安全和“双碳”目标的达成&#xff0c;充电桩是需要智能电网支持&#xff0c;…

Linux 各目录

Linux 是一个非常严谨的操作系统&#xff0c;每个目录都有自己的作用&#xff0c;这些作用是固定的&#xff0c;没有特殊情况&#xff0c;应严格执行&#xff1b; Linux 中所有东西以文件形式存储和管理&#xff0c;命令也不例外&#xff1b; 以下四个 bin 是二进制文件&…

linux C++ onnxruntime yolov8 视频检测Demo

linux C onnxruntime yolov8 视频检测Demo 目录 项目目录 效果 ​编辑CMakeLists.txt 代码 下载 项目目录 效果 ./yolov8_demo --help ./yolov8_demo -c2 -ptrue ./yolov8_demo -c1 -strue CMakeLists.txt # cmake needs this line cmake_minimum_required(VERSION 3…

力扣最热一百题——3.最长连续序列

目录 题目链接&#xff1a;128. 最长连续序列 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示 解法一&#xff1a;排序双指针剪枝 思路 1. 获取数组长度并进行特判 2. 对数组进行排序 3. 初始化变量 4. 遍历数组并寻找最长连续子序列 5. 返回结果 总结…

Linux笔记-对.a静态库的进一步理解(2024-04-09)

过程 问&#xff1a; Linux中生成.a库时候&#xff0c;如果代码里面调用了一些只引用未定义的函数&#xff0c;gcc不报错&#xff0c;但能生成对应的.a文件&#xff0c;这是为什么&#xff1f;再写一个执行程序去调用.a库时&#xff0c;链接时就会报这个.a库未定义的引用&…

列举excel中调整行高列宽的五种方法

列举excel中调整行高列宽的五种方法 在Excel中调整行高列宽的方法有以下五种&#xff1a; 使用鼠标手动调整行高列宽&#xff1a;将鼠标悬停在行或列的边界上&#xff0c;光标会变成双向箭头&#xff0c;此时按住鼠标左键并拖动边界即可调整行高或列宽。 使用快捷键调整行高列…

node和npm安装;electron、 electron-builder安装

1、node和npm安装 参考&#xff1a; https://blog.csdn.net/sw150811426/article/details/137147783 下载&#xff1a; https://nodejs.org/dist/v20.15.1/ 安装&#xff1a; 点击下载msi直接运行安装 安装完直接cmd打开可以&#xff0c;默认安装就已经添加了环境变量&…

vue3通过html2canvas dom转图片复制到剪贴板和dom转图片并下载

代码实现 <template><div class"page"><div id"to-img-dom"><strong>我是图片标题</strong><p>我是内容&#xff0c;我是内容&#xff0c;我是内容&#xff0c;我是内容&#xff0c;我是内容&#xff0c;我是内容&am…

Jupyter notebook 快速入门

1、什么是jupyter notebook Jupyter Notebook是一个交互式笔记本环境&#xff0c;可以在其中同时编写和运行代码&#xff0c;以及进行数据分析和可视化。它支持多种编程语言&#xff08;如Python、R、Julia等&#xff09;&#xff0c;并提供了丰富的功能和工具供用户使用。Jup…

如何减少网站延迟?

什么是网络延迟&#xff1f; Web 延迟描述了网站响应用户请求所花费的时间。它是网络性能的一个重要因素&#xff0c;因为它决定了用户访问网站内容并与之交互的速度。当延迟很高时&#xff0c;网站会变得缓慢且反应迟钝&#xff0c;从而导致用户不满意。延迟可能由多种因素引…

如何用 WinDbg 调试Linux上的 .NET程序

一&#xff1a;背景 1. 讲故事 最新版本 1.2402.24001.0 的WinDbg真的让人很兴奋&#xff0c;可以将自己伪装成 GDB 来和远程的 GDBServer 打通来实现对 Linux 上 .NET程序进行调试&#xff0c;这样就可以继续使用熟悉的WinDbg 命令&#xff0c;在这个版本中我觉得 WinDbg 不…

数据结构C++——二叉树和树

文章目录 一、树二、二叉树三、二叉树的特性特性1. 包含n (n> 0 )个元素的二叉树边数为n-1特性 2: 若二叉树的高度为h,h≥0,则该二叉树最少有h个元素,最多有2^h-1 个元素特性3:包含n(n≥0)个元素的二叉树的高度最大为n,最小为ceiling(log2(n+1))特性4. 完全二叉树四、二…

基于微信小程序+SpringBoot+Vue的高校校园交友(带1w+文档)

基于微信小程序SpringBootVue的高校校园交友(带1w文档) 基于微信小程序SpringBootVue的高校校园交友(带1w文档) 在目前的情况下&#xff0c;可以引进一款高校校园交友微信小程序这样的现代化管理工具&#xff0c;这个工具就是解决上述问题的最好的解决方案。它不仅可以实时完成…

代码随想录 day 21 二叉树

第六章 二叉树part08 669. 修剪二叉搜索树 这道题目比较难&#xff0c;比 添加增加和删除节点难的多&#xff0c;建议先看视频理解。 题目链接/文章讲解&#xff1a; https://programmercarl.com/0669.%E4%BF%AE%E5%89%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.html…

行业、客户双认可!路凯智行精彩亮相新疆煤博会

7月18日&#xff0c;2024丝路矿业合作论坛、第14届中国新疆国际矿业与装备博览会、第19届中国新疆国际煤炭工业博览会在新疆国际会展中心举行&#xff0c;此次论坛和展会吸引了全国26个省区市和德国、美国、日本、挪威、芬兰、法国、巴基斯坦、俄罗斯、白俄罗斯、乌兹别克斯坦等…

企业如何应对大模型落地的四大挑战?

近年来&#xff0c;人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术取得了突飞猛进的发展&#xff0c;其中大模型&#xff08;如GPT-3、GPT-4、BERT等&#xff09;因其强大的数据处理和分析能力&#xff0c;受到了企业的高度重视。大模型在自然语…

使用nginx实现一个端口和ip访问多个vue前端

前言&#xff1a;由于安全组要求&#xff0c;前端页面只开放一个端口&#xff0c;但是项目有多个前端&#xff0c;此前一直使用的是一个前端使用单独一个端口进行访问&#xff0c;现在需要调整。 需要实现&#xff1a;这里以80端口为例&#xff0c;两个前端分别是&#xff1a;p…

[用AI日进斗金系列]用码上飞在企微接单开发一个项目管理系统!

今天是【日进斗金】系列的第二期文章。 先给不了解这个系列的朋友们介绍一下&#xff0c;在这个系列的文章中&#xff0c;我们将会在企微的工作台的“需求发布页面”中寻找有软件开发需求的用户 并通过自研的L4级自动化智能软件开发平台「码上飞CodeFlying」让AI生成应用以解…

可以免费合并pdf的软件 合并pdf文件的软件免费 合并pdf的软件免费

在数字化办公的今天&#xff0c;pdf格式因其稳定性和跨平台兼容性被广泛使用。然而&#xff0c;当我们需要将多个 pdf 文件合并为一个时&#xff0c;却往往感到力不从心。本文将为你介绍几款强大的pdf文件合并软件&#xff0c;让你轻松管理文档。 方法一、使用pdf转换器 步骤1…

Vue3 对比 Vue2

相关信息简介2020年9月18日&#xff0c;Vue.js发布3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;海贼王&#xff09; 2 年多开发, 100位贡献者, 2600次提交, 600次 PR、30个RFC Vue3 支持 vue2 的大多数特性 可以更好的支持 Typescript&#xff0c;提供了完整的…