RabbitMq如何确保消息不丢失

news2024/11/15 15:38:23

问题:在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重启期间生产者消息投递失败,导致消息丢失,需要手动处理和恢复。于是,我们开始思考,如何才能进行 RabbitMQ 的消息可靠投递呢? 特别是在这样比较极端的情况,RabbitMQ 集群不可用的时候,无法投递的消息该如何处理呢?

解决方案就是缓存,比如当生产者发送消息到交换机时,但交换机不存在,我们应该将消息放入缓存中;或者交换机存在,队列不存在了,当交换机发送不到队列中也应该将消息放入缓存。然后在缓存中配置一个定时任务,对没有发送成功的消息重新进行投递。这样就避免了消息丢失的情况。

回调接口——消息确认

接下来我们通过代码实现以上机制,架构图如下所示:我们要解决问题就是如果图中的交换机或者队列出现问题,应该将消息进行缓存处理,防止消息丢失,具体的实现就是通过生产者的回调接口ConfirmCallback来实现。

1️⃣ 修改配置文件

在配置文件当中需要添加配置表示开启发布消息成功到交换器后会触发回调方法

NONE:禁用发布确认模式,是默认值

CORRELATED:发布消息成功到交换器后会触发回调方法

SIMPLE:经测试有两种效果,其一效果和 CORRELATED 值一样会触发回调方法;其二在发布消息成功后使用 rabbitTemplate 调用 waitForConfirms 或 waitForConfirmsOrDie 方法等待 broker 节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是 waitForConfirmsOrDie 方法如果返回 false 则会关闭 channel,则接下来无法发送消息到 broker

👂这个层次是在交换机层次做的工作,保证消息被正确发送到了交换机。

通过实现一个RabbitTemplate.ConfirmCallback接口,将接口注入到RabbitTemplate中,当消息发送到交换机后就会触发这个回调。如果失败了可以考虑进入死信队列或者重新发送。但是做不到队列层面的工作。

 /**
     * 交换机确认回调方法
     *
     * @param correlationData 保存回调消息的ID以及相关信息
     * @param ack             表示交换机是否收到消息(true表示收到)
     * @param cause           表示消息接收失败的原因(收到消息为null)
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = correlationData != null ? correlationData.getId() : "";
        if (ack) {
            log.info("交换机已经收到ID为:{}的消息", id);
        } else {
            log.info("交换机还未收到ID为:{}的消息,原因为:{}", id, cause);
        }
    }
回调接口——消息回退

我们知道在仅开启了生产者确认机制的情况下,交换机接收到消息后,会直接给消息生产者发送确认消息,如果发现该消息不可路由,那么消息会被直接丢弃,但此时生产者是不知道消息被丢弃这个事件的。那么如何让无法被路由的消息能够让生产者感知并做出处理呢

我们可以通过设置 mandatory 参数可以在当消息传递过程中不可达目的地时将消息返回给生产者。

在配置文件当中需要添加配置表示开启消息路由失败后会触发消息回退回调方法

👂通过实现 RabbitTemplate.ReturnsCallback 接口

    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.info("消息{}:,被交换机{}退回,退回原因:{},路由key:{}",
                new String(returned.getMessage().getBody()),
                returned.getExchange(),
                returned.getReplyText(),
                returned.getRoutingKey());
    }

备份交换机

前面我们提到交换机如果出现了问题接受不到消息,我们就让交换机进行消息确认,让生产者重新发消息。如果队列出问题收不到消息,我们就进行消息回退,也是让生产者重新发消息。此外,还有一种解决方法就是给交换机添加一个备份交换机,有了备份交换机之后可以不用讲消息回退给生产者,而是将无法投递的消息交给备份交换机,让备份交换机通过自己的路由以及自己的队列发送给消费者,这样也能达到一个消息不丢失的目的。并且这种方式还能建立一个报警队列,用独立的消费者进行监测和报警。

当回调函数和备用交换机一起使用的时候,备份交换机优先级高。

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

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

相关文章

RLVF:避免过度泛化地从口头反馈中学习

人工智能咨询培训老师叶梓 转载标明出处 大模型在不同行业和个人中的广泛应用要求模型能够根据具体的用户反馈进行调整或定制,以满足细微的要求和偏好。虽然通过高层次的口头反馈来指定模型调整非常方便,例如“在给老板起草电子邮件时不要使用表情符号”…

Ubuntu 20.04 几种微信安装错误汇总,最后成功

1. wine 安装 参考 Ubuntu 20.04.2 LTS安装 最新版 微信(wine) 1.1 连网下载文件 在终端执行 winetricks riched20下载不了 W2KSP4_EN.EXE 和 InstMsiW.exe 两个文件 可以网页端下载,或者 wget https://web.archive.org/web/2000/https:…

MySQL——数据库的设计、事务、视图

文章目录 数据库的设计1.多表之间的关系2.实现关系3.数据库设计的范式 事务1.事务的基本介绍2.事务的四大特征ACID3.事务的隔离级别(了解即可) 视图1.什么是视图?2.视图创建及使用方法3.注意事项4.为什么使用视图 数据库的设计 1.多表之间的…

GIS,矢量瓦片加载速度优化

文章目录 一、前言二、矢量瓦片的基础知识三、矢量切片加载速度优化3.1 地图缩编3.2 矢量瓦片中的图层根据显示层级定制3.3 矢量瓦片中的图层字段要按需定制3.4 多个图层合并为矢量切片图层组发布 四、总结 一、前言 单个矢量瓦片的大小并没有固定的上限,这意味着在…

一款功能强大且完全免费的在线AI抠图工具,还可以制作证件照

适用于人像、宠物、汽车等物品的智能抠图。它利用先进的算法和发丝级AI技术,能够快速精准地完成图片背景移除,并提供透明背景、场景切换和证件照制作等多种增值服务。此外,还支持批量处理和多种图片格式,适合不同用户的需求。无论…

【xilinx】如何从 Vivado GUI 启用/禁用 IP Core container

问题描述 如何从 Vivado GUI 启用/禁用 IP 核容器? 解决方案 要通过 GUI 启用/禁用 2023.1 之前的 Vivado 版本中的 IP 核容器,请按照以下步骤操作: 选择设置 -> IP -> 使用核心容器 在 Vivado 2023.1 及更高版本中,请按照…

中国自动驾驶出租车冲击网约车市场

近年来,中国的自动驾驶技术迅速发展,对传统网约车市场构成了越来越大的冲击。随着科技巨头百度旗下的萝卜快跑等公司加速推广无人驾驶出租车,这一趋势引发了广泛的讨论和担忧。 自动驾驶技术的迅猛发展 中国自动驾驶行业正处于快速发展阶段&…

ComfyUI系列——新手安装ComfyUI,就是这么简单!

前言 比较Midjoury、WebUI和ComfyUI 在了解ComfyUI的时候,还有其它两款类似的产品,于是就搜集了一下资料,以下是Midjoury、WebUI(通常指的是Stable Diffusion Web UI)和ComfyUI三者之间的异同点对比表。 特性Midjou…

Linux系统通过安装docker容器部署mysql服务

一、查看主机内核版本,关闭防火墙相关信息 二、直接yum安装docker 安装的18.09版本,也可以rpm安装最新版 yum install docker # docker --version Docker version 18.09.0, build a8959d5三、安装完成直接启动并查看状态 systemctl start docker syst…

Linux内核编程(十二)热插拔

本文目录 一、知识点1. 热插拔概念2. 热插拔机制3. Netlink机制 二、内核发送uevent事件到用户空间1. kobject发送uevent事件2. udevadm命令查看★示例代码:★优化:完善kset_uevent_ops(热插拔事件结构体) 三、用户空间使用Netlin…

MySQL数据分析进阶(十二)设计数据库——PART2

※食用指南:文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记,笔记整理比较粗糙,主要目的自存为主,记录完整的学习过程。(图片超级多,慎看!) 【中字】SQL进阶教程 | 史上最易懂S…

大模型(LLMs)LLM生成SFT数据方法面

一、SFT数据集如何生成? SFT数据集构建通常有两种方法:人工标注和使用LLM(比如GPT-4)来生成的,人工标注对于构 建垂直领域比较合适,可以减少有偏数据,但是成本略高;使用LLM生成&…

【算法设计题】计算有向图G中每个结点的入度和出度,第4题(C/C++)

目录 第4题 计算有向图G中每个结点的入度和出度 得分点(必背) 题解:计算有向图G中每个结点的入度和出度 数据结构定义 边表结点 顶点表结点 图的邻接表存储表示 计算图G中每个结点的入度和出度 详细解释 1. 初始化入度和出度数组 2…

容器适配器的介绍和模拟实现

💗 💗 博客:小怡同学 💗 💗 个人简介:编程小萌新 💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞 Stack的介绍 stack是一种容器适配器,专门用在具有后进先出操作的上…

如何看到公司所有员工的收发件,并以员工名义一键发信

对于企业管理层来说, 了解并监控员工的企业邮箱成为了日常工作中的一部分。这不仅可以帮助企业更好地掌握业务进展, 还能够提高工作效率。本文将详细介绍如何通过Zoho邮箱实现这一目标, 包括相关的技术原理、实现的好处以及具体的实施步骤。 一、实现的技术: POP3 和 IMAP 要…

C++类和对象(2)——构造函数和析构函数

###前言:此文主要介绍C中的六种默认成员函数;默认的意思就是我们不写编译器会自动生成;这些函数在类里面自动生成;但是我们也可以自己写;学习这几种默认成员函数从两个方面入手: (1&#xff09…

“AI大语言模型+”助力大气科学相关交叉领域实践技术应用

查看原文>>>“AI大语言模型”助力大气科学相关交叉领域实践技术应用 目录 专题一、预备知识 专题二、科研辅助专题 专题三、可视化专题——基于GPT实现 专题四、站点数据处理 专题五、WRF专题——基于GPT和Python实现 专题六、遥感降水专题——基于GPT和Python…

#java学习笔记(面向对象)----(未完结)

一基础相关知识点: 1. 一个对象的调用 首先我们创建一个Phone类 public class Phone {//成员变量String name;int age;String favourite;//成员方法public void myName(){System.out.println(name);}public void myAge(){System.out.println(age);}public void m…

免费写作神器,自动生成高质量文章

在当今数字化的时代,信息的传播和创作变得前所未有的重要。无论是企业的营销推广、个人的博客写作,还是学术研究报告,优质的文章都能发挥巨大的作用。而随着人工智能技术的飞速发展,免费的ai写作工具应运而生,为我们带…

虚拟内存惹

二、理解 虚拟内存 虚拟内存存在的原因物理地址和虚拟地址虚拟内存的其他介绍 虚拟内存存在的原因 计算机系统有两种地址:1、物理地址 2、虚拟地址 物理地址:是指真实的地址,是物理存在的,比如RAM、flash等 虚拟地址:…