当前位置: 首页 > news >正文

539、RabbitMQ详细入门教程系列 -【100%消息投递消费(一)】 2022.08.31

目录

    • 一、前言概述
    • 二、事务TX
      • 2.1 相关操作
      • 2.2 代码示例
      • 2.3 总结
    • 三、确认Confirm
      • 3.1 相关操作
      • 3.2 代码示例
      • 3.3 注意事项
    • 四、参考链接

一、前言概述

生产者生产消息到消费者消息消费,中间需要生产者将消息发送到交换器,再由交换器路由到队列存储,然后消费者进行消息消费。在没有任何设置情况下,中间可能存在以下几种情况导致消息丢失:

在这里插入图片描述

  1. 消费者将消息发送到交换器因为RabbitMQ内部原因丢失消息
  2. 交换器将消息路由到队列,因为队列不存在等因素导致消息丢失
  3. 队列中存储的消息在消费者未消费时RabbitMQ服务宕机导致消息丢失
  4. 消费者消费消息时消费者宕机未处理完消息导致消息丢失

针对上述情况,本文将根据每个节点讲述如何操作确保消息投递的可靠性,同时在保障可靠性的情况下可能会引发系列如消息重复等问题,也是本文将会涉及到的重点

二、事务TX

理解数据库的事务就是将多次操作原子化,统一提交回滚实现数据一致性。RabbitMQ事务可能与之前数据库等事务有一定差别,当然也是支持消息的提交与回滚操作。事务是解决生产者发送消息到交换器消息丢失问题的方案之一

2.1 相关操作

RabbitMQ中的事务实现有如下两个个主要步骤:
在这里插入图片描述

  1. 将通信的信道设置为事务模式
  2. 事务提交/事务回滚

2.2 代码示例

        // 将信道设置为事务模式
        channel.txSelect();
        // 发送消息
        try {
            channel.basicPublish(bindingKey, bindingKey, false, false, null, messgae.getBytes("UTF-8"));
            // 提交事务
            channel.txCommit();
        }catch (Exception e){
            // 异常回滚事务,发生异常的时候可以尝试重发或者记录等操作
            channel.txRollback();
        }

2.3 总结

事务机制的确认需要等待上一条消息发送完毕反馈之后才能进行第二条消息发送,这样的操作将会对于使用RabbitMQ而言感觉就是暴殄天物。如果是想要发送多条消息只能循环操作,但是注意如果没有将channel信道设置为事务模式不能进行事务操作,不然会抛出异常。最后一点就是信道设置为事务模式只需要操作一次即可

三、确认Confirm

事务机制对于RabbitMQ性能消耗是灾难性的,针对生产者到交换器消息丢失处理提出了全新的轻量级处理方式。发送发确认机制confirm,该操作编码上会有很多地方都在讲什么等待确认、批量确认、异步确认。一切为了生产,所以本文将只会介绍生产用的异步确认方式

3.1 相关操作

RabbitMQ的生产发送确认实现由以下三个部分构成:

  • 将信道channel设置为确认模式
  • 增加确认监听Listener
  • 处理监听结果

3.2 代码示例

  • 每个通道发送到RabbitMQ的Broker中都会有唯一的编码
  • 生产端最好使用有序队列存储发送的消息,方便确认后的删除
  • 创建Channel通道时可以指定唯一编码,标识该通道
        // 设置confirm消息发送确认机制
        channel.confirmSelect();
        // 增加确认机制监听器
        channel.addConfirmListener(new ConfirmListener() {
            /**
             * 成功确认
             * deliveryTag 表示消息的唯一标识
             * multiple 本次确认是否为批量操作
             */
            @Override
            public void handleAck (long deliveryTag, boolean multiple) throws IOException {
                // 删除有序集合中的消息
                if (! multiple){
                    // 根据坐标删除消息
                }else {
                    // 批量删除消息
                }
            }
    
            /**
             * 失败确认
             * deliveryTag 表示消息的唯一标识
             * multiple 本次确认是否为批量操作
             */
            @Override
            public void handleNack (long deliveryTag, boolean multiple) throws IOException {
                // 可以根据deliveryTag做重试操作等
            }
        });

3.3 注意事项

在这里插入图片描述

  • 共存:事务与确认机制不能共存,不然会异常
  • 查验:通过RabbitMQ可视化监控界面可看到Channels栏Mod属性T表示事务,C表示监听确认
  • 有序:因为RabbitMQ生成的序列deliveryTag是由小到大自动递增的,所以最好存储消息的时候考虑到
  • 顺序性,更方便通过deliveryTag定位到消息进行操作

四、参考链接

[01] RabbitMQ详细入门教程系列 -【100%消息投递消费(一)】

相关文章:

  • 基于信贷业务的量化风险评估简述
  • 项目经理如何做好任务分解,制定项目计划
  • 高级JAVA面试题详解(一)——CurrentHashMap、HashMap、HashTable的区别
  • Dart 2.18 发布,Objective-C 和 Swift interop
  • learn threejs (最小化例子)
  • Flask学习(四)-------蓝图
  • 牛客多校2 - Ancestor(LCA,前后缀)
  • 【毕业设计】深度学习垃圾分类系统 - 机器视觉
  • Linux 编写shell脚本记录操作用户日志信息
  • 从零开始配置vim(19)——终端配置
  • 岑溪洁净实验室设计布局规划总结
  • 要不要做全链路压测
  • node.js云学堂微信小程序学习系统的设计与实现毕业设计源码011735
  • 前端知识3-JavaScript
  • 函数和二维数组
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 4. 路由到控制器 - Laravel从零开始教程
  • create-react-app做的留言板
  • express.js的介绍及使用
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Laravel 菜鸟晋级之路
  • leetcode388. Longest Absolute File Path
  • Less 日常用法
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 成为一名优秀的Developer的书单
  • 高程读书笔记 第六章 面向对象程序设计
  • 力扣(LeetCode)56
  • 为视图添加丝滑的水波纹
  • 小试R空间处理新库sf
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 与 ConTeXt MkIV 官方文档的接驳
  • 正则表达式小结
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​​​​​​​​​​​​​​Γ函数
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • $.ajax()方法详解
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • **PHP分步表单提交思路(分页表单提交)
  • ./configure,make,make install的作用
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .equals()到底是什么意思?
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Core WebAPI中封装Swagger配置
  • .net 中viewstate的原理和使用
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET开发不可不知、不可不用的辅助类(一)
  • /*在DataTable中更新、删除数据*/
  • ??javascript里的变量问题