RabbitMQ如何保证消息的可靠性

news2024/11/26 3:50:12

文章目录

  • 可靠性分析
  • 可靠性方案
  • 可靠性实现
    • 确认Exchange接收到消息
    • 确认Queue接收到消息
    • 保证Queue及其数据持久化
    • 保证消费者的正常消费
      • 重复消费问题
      • 消息丢失问题

可靠性分析

RabbitMQ如何保证消息的可靠?如RabbitMQ基础概念中的架构模型
在这里插入图片描述
可以看到一条消息的传递过程:

  1. 发布者和RabbitMQ建立连接发送消息至交换机。
  2. 交换机和队列绑定,将消息路由到队列中。
  3. 消费者和RabbitMQ建立连接指定某个队列的消息进行消费。

在这过程中以下几个环节可能会丢失消息:

  1. 发布者到交换机环节。
  2. 交换机到队列环节。
  3. 队列到消费者环节。

如下图
在这里插入图片描述


可靠性方案

所以要保证消息的可靠性需要做到以下几点:

  1. 发布者需确认交换机接收到消息。
  2. 发布者需确认队列接收到消息。
  3. 保证队列及其中的数据持久化。
  4. 保证消费者的正常消费。

如何做到以上几点?RabbitMQ为了适应各个场景的使用,以上的功能需要开发者按照定义自行设置实现。


可靠性实现

以下实现为Java整合RabbitMQ实现,参考Java整合RabbitMQ实现生产消费(7种通讯方式)

确认Exchange接收到消息

构建channel时添加确认监听机制,当消息未发送至交换机时做补偿措施。

 channel.addConfirmListener((sequenceNumber, multiple) -> {
            System.out.println("消息成功发送到交换机");
        }, (sequenceNumber, multiple) -> {
            System.err.println("消息未发送到交换机,补偿操作。");
        });

确认Queue接收到消息

  1. 构建channel时添加return监听机制,当消息未路由至队列时做补偿措施。
channel.addReturnListener((replyCode, replyText, exchange, routingKey, basicProperties, body) -> {
            System.err.format("消息 %s 未路由到指定队列: %s, replyText: %s,replyCode: %d%n", body, routingKey, replyText, replyCode);
        });
  1. 发布消息时设置消息mandatory为true,开启return机制。
 channel.basicPublish("", "",true, "", "");

保证Queue及其数据持久化

  1. 构建队列时持久化队列。
 //构建队列,queueDeclare("队列名称","是否持久化队列","是否只允许一个队列消费","长时间未使用是否删除","其他参数")
  channel.queueDeclare("", true, false, false, null);
  1. 发布消息时设置消息持久化属性。
//设置消息持久化
AMQP.BasicProperties basicProperties = new AMQP.BasicProperties.Builder().deliveryMode(2).build();
channel.basicPublish("", "",true, basicProperties, "");     

保证消费者的正常消费

当消息持久化至队列时已经保证了消息的可靠投递,为保证消息的正常消费,需要解决重复消费和消息丢失问题。

重复消费问题

  1. 业务处理完成,但是ack失败,消息被扔进队列,导致重复消费。
  2. 业务处理过程中,进程宕机,恢复进程后消费未ACK的消息导致重复消费。

针对第一个场景的解决方案:设置手动ACK,并且业务处理和ack操作在一个事务中。

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            //消息处理后手动ACK
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        };
// ack为false
channel.basicConsume("", false, deliverCallback, consumerTag -> {
});

针对第二个场景的解决方案:发布消息时设置业务唯一标识,在消费后进行存储,如果有相同标识前来消费直接拒绝即可(具体业务具体分析)。设置业务唯一标识方式:

String correlationId = UUID.randomUUID().toString();
AMQP.BasicProperties basicProperties = new AMQP.BasicProperties.Builder().correlationId(correlationId).build();
channel.basicPublish("", "", basicProperties, "");     

消息丢失问题

在以下场景中可能会发生消息丢失问题:

  1. 业务处理失败,但是ack成功,导致消息丢失。

解决方案:设置手动ACK,并且业务处理和ack操作在一个事务中。

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

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

相关文章

还在用HttpUtil?SpringBoot 3.0全新HTTP客户端工具来了,用起来够优雅~

我们平时开发项目的时候,经常会需要远程调用下其他服务提供的接口,于是我们会使用一些HTTP工具类比如Hutool提供的HttpUtil。前不久SpringBoot 3.0发布了,出了一个Http Interface的新特性,它允许我们使用声明式服务调用的方式来调…

PreScan快速入门到精通第四十讲目标边界传感器

边界矩形传感器提供了关于传感器可检测物体的边界矩形的信息,并作为对摄像机输入的边界矩形算法的参考。一个例子是行人识别算法,该算法用于检测夜间、雾、雨或雪等恶劣照明条件下的行人。输出的检测到的边界矩形是按距离排序的--最近的在前。 注意:边界矩形传感器不检测(或…

Qt扫盲-QDoubleSpinBox理论总结

QDoubleSpinBox理论总结1. 简述2. 调值与值转换3. 信号4. 修饰&外观1. 简述 QDoubleSpinBox 主要是对于浮点数据的输入进行便捷的封装。QDoubleSpinBox和QSpinBox的使用基本一致,只是有些控制有些不同嘛。比如对于浮点数的小数点精度位数的控制啦。 QDoubleSpi…

第五章. 可视化数据分析图表—常用图表的绘制4—箱形图,3D图表

第五章. 可视化数据分析图 5.3 常用图表的绘制4—箱形图,3D图表 本节主要介绍常用图表的绘制,主要包括箱形图,3D柱形图,3D曲面图。 1.箱形图(matplotlib.pyplot.boxplot) 箱形图又称箱线图、盒须图或盒式…

你还在为 “动态规划” 发愁吗?看完本秘籍,带你斩杀这类题~

目录 前言 一、动态规划——解题思路 二、动态规划——模板以及题目 2.1、Fibonacci 2.2、字符串分割(Word Break) 2.3、三角矩阵(Triangle) 2.4、路径总数(Unique Paths) 2.5、最小路径和(Minimum Path Sum) 2.6、背包问题 2.7、回文串分割(Pa…

第08讲:使用脚手架创建vue项目

一、安装NodeJS 二、配置环境变量 2.1、软件安装完成之后配置npm的环境变量 第1步:获取npm安装位置 使用管理员身份打开CMD,用如下命令获取npm的安装位置: npm config list第2步:配置环境变量 将以上获取的路径保存到path变…

flask请求与响应、session执行流程

目录 请求对象 响应对象 session的使用和原理 闪现(flash) 请求扩展 蓝图 请求对象 请求对象request是全局的,需要导入这个全局的request,在哪个视图函数中就是当次的request对象 请求数据: request.method # 获取提交的方法 …

文件包含漏洞简介

今天继续给大家介绍渗透测试相关知识,本文主要内容是文件包含漏洞简介。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负! 再次强调:严禁对未授权设备…

一些好玩的js小作品

今天小编给大家带来了一些很实用的js小作品,下面请一看究竟。 1、计算详细年龄工具js脚本 2、检测是否安装Flash插件及版本号js脚本 3、无法查看源码的页面 4、面积换算js脚本 5、体积和容积换算js脚本 6、长度换算js脚本 7、重量换算js脚本 8、只能输入汉字…

记一些女装数据分析

文章目录服装维度女装生命周期门店维度常见度量值衍生指标服装维度 尺码:XS、S、M、L、XL颜色:黑、红、蓝、白……一级分类:上半身、下半身、全身季节:春、夏、秋、冬价格类型:正价、特价、折扣价、降价、优惠券…价格…

Android自定义ViewGroup布局进阶,完整的九宫格实现

自定义ViewGroup九宫格 前言 在之前的文章我们复习了 ViewGroup 的测量与布局,那么我们这一篇效果就可以在之前的基础上实现一个灵活的九宫格布局。 那么一个九宫格的 ViewGroup 如何定义,我们分解为如下的几个步骤来实现: 先计算与测量九…

【Linux学习】进程信号

文章目录前言一、信号初识1. 信号的概念2. Linux中的普通信号3. 信号的处理二、信号产生1. 终端按键产生信号2. 系统调用发送信号2.1 kill函数2.2 raise函数2.3 abort函数3. 由软件条件产生信号3.1 SIGPIPE信号3.2 alarm函数4. 由硬件异常产生信号三、信号阻塞1. 信号阻塞即其他…

[前端面试题]flex上下布局

[前端面试题]flex上下布局 [万字长文]一文教你彻底搞懂flex布局 [CSS]一些flex的应用场景 页面中有两个元素。元素bottom固定在底部,靠内容来撑开;而元素top在上边,高度自适应,自动铺满除bottom剩下的空间,且top内容…

第十四届蓝桥杯集训——JavaC组第十篇——分支语句

第十四届蓝桥杯集训——JavaC组第十篇——分支语句 目录 第十四届蓝桥杯集训——JavaC组第十篇——分支语句 if单分支 if单分支语法 if单分支语句示例 单分支例题: 连续单分支示例 if简写语法 if双分支语句 if双分支语法 if双分支语法示例 if双分支简写法…

全栈jmeter接口测试教程之Jmeter+ant+jenkins实现持续集成

jmeterantjenkins持续集成 一、下载并配置jmeter 首先下载jmeter工具,并配置好环境变量;参考:https://www.cnblogs.com/YouJeffrey/p/16029894.html jmeter默认保存的是.jtl格式的文件,要设置一下bin/jmeter.properties,文件内容…

圣诞节快来了~用python做一个粒子烟花震撼众人赚个女孩回来吧~

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 准备 准备一下你运行效果的背景图 以及一首你喜欢或那你女朋友喜欢的音乐 效果 代码展示 导入模块 import random import pygame as py import tkinter as tk from time import time, sleep fr…

Fuzzing with Data Dependency Information阅读笔记

相关数据 论文:https://www.s3.eurecom.fr/docs/eurosp22_mantovani.pdf 开源代码:https://github.com/elManto/DDFuzz 论文背景 这篇论文是2022年发表在sp上的一篇论文,也是在afl的基础上进行改进的一篇论文。afl是在afl的基础上进行整合…

第二十六章 linux-输入子系统二

第二十六章 linux-输入子系统二 文章目录第二十六章 linux-输入子系统二框架三个重要结构体struct input_devstruct input_handlerstruct input_handle框架 Linux系统支持的输入设备繁多,例如键盘、鼠标、触摸屏、手柄或者是一些输入设备像体感输入等等&#xff0c…

[附源码]Python计算机毕业设计电子投票系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

30岁转行网络安全来得及吗?有发展空间吗?

30岁转行网络安全来得及吗?有发展空间吗? 现阶段,很多30岁左右的人群都面临就业难的问题,尤其是对于年龄已过30.没有一技之长的人。现阶段,网络安全行业已成了风口行业,也有很多30岁人群也想转行学习网络安全,但又担…