RabbitMQ速通--04消息可靠性投递与特殊队列

rabbitmq消息投递失败 使用Confirm模式和确保消息从生产者正确发送到交换机和队列。使用手动消息确认机制处理消费者无法处理的消息。配置死信队列处理无法处理或过期的消息。确保消息处理逻辑具有幂等性,以防止重复处理导致的数据不一致。通过这些方法,可以提高消息系统的可靠性和健壮性,确保消息不会丢失或重复处理。 阅读详情

消息可靠性投递

故障概述

  • 故障情况1:消息没有发送到消息队列
    • 解决方式1:在生产者端分别针对交换机和队列来进行确认,当没能成功发送到消息队列服务器上,则尝试重新发送。
    • 解决方式2:为目标交换机指定备份交换机,当目标交换机投递失败时,把消息投递到备份交换机
  • 故障情况2:消息队列服务器宕机导致内存中消息丢失
    • 解决方式:将消息持久化(已经默认实现)
  • 故障情况3:消费端宕机或抛出异常导致消息没被成功消费
    • 解决方式:消费端消费成功后,给服务器返回ACK消息,之后消息队列服务器才会删除该消息。当消费端消费信息失败,就给服务端返回NACK信息,同时把消费恢复为待消费的状态,这样就可以再次取回消息(需要消费端接口支持幂等性)

生产者端消息确认机制

  1. 在配置文件中添加相应的配置项
  2. 在配置类中声明相应回调函数
  3. 为RabbitTemplate设置增强

配置文件

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    publisher-confirm-type: CORRELATED # 交换机的确认
    publisher-returns: true # 队列的确认

配置类

@Configuration
@Slf4j
public class RabbitConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback {

    // 从容器中取出rabbitTemplate
    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 初始化rabbitTemplate后将下面两个回调添加进去
    // 该注解可以指定在对象创建后立即执行,在spring中使用时,可以保证对象在初始化之后执行该方法
    @PostConstruct
    public void initRabbitTemplate() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    // 消息发送到交换机无论成功与否都会执行该方法
    // 三个参数分别描述:相关数据,是否接收成功,接收失败的原因
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        log.info("相关数据" + correlationData);
        log.info("交换机是否接收成功" + b);
        if(!b){log.info("交换机接受失败的原因" + s);}
    }

    // 只有当发送到队列失败才会回调该方法
    // 该参数用以描述相关信息
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.info("消息主体" + new String(returnedMessage.getMessage().getBody()));
        log.info("应答码" + returnedMessage.getReplyCode());
        log.info("应答码描述" + returnedMessage.getReplyText());
        log.info("消息使用的交换机"+returnedMessage.getExchange());
        log.info("消息使用的路由键"+returnedMessage.getRoutingKey());
    }
}

测试

@SpringBootTest
class ConfirmProducerApplicationTests {

    // 需要提前创建该队列
    public static final String EXCHANGE_DIRECT = "exchange.direct.order";
    public static final String Routing_KEY = "order";

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    void testSendMessage() {
        rabbitTemplate.convertAndSend(EXCHANGE_DIRECT, Routing_KEY, "Hello World");
    }

}

备份交换机

若目标交换机出现故障,导致生产者消息不能被成功消费消息。此时,我们通常采用备份交换机来进行故障转移,备份交换机可以绑定另外一个队列,让另一个消费者对其进行监听,用以记录错误日志方便后续人员排查

备份交换机的创建可以直接在rabbitmq面板中进行。该交换机类型必须是fanout(从目标交换机将消息转到备份交换机时不带路由键)

目标交换机的创建需要在备份交换机之后进行,因为指定备份交换只能在创建时通过点击Add Alternate exchange,并且填写备份交换机名进行。

消费者端确认机制

  1. 在配置文件中将消息确认模式改为手动确认
  2. 在消费者监听器添加相应调用
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: manual # 将消息确认模式改为手动

消费者

@Component
@Slf4j
public class MyMessageListener{
  public static final String QUEUE_NAME = "queue.order";

  @RabbitListener(queues = {QUEUE_NAME})
  public void processMessage(String dataString, Message message, Channel channel) throws IOException {

    // 获取当前消息的deliveryTag
    long deliveryTag = message.getMessageProperties().getDeliveryTag();

    try{
      log.info("消费端 消息内容" + dataString);
      // 返回ACK信息
      // 第一个参数为deliveryTag,可以看作是每条消息的id(就算是广播的消息也是全局唯一)
      // 第二个参数若为true时,则对此消息还有之前的全部批量操作,若为false则只会对当前消息进行操作
      channel.basicAck(deliveryTag,false);
    } catch (Exception e) {
      // 获取当前消息是否是重复投递的
      Boolean redelivered = message.getMessageProperties().getRedelivered();

      if(redelivered){channel.basicNack(deliveryTag,false,false);}

      // 返回NACK消息
      // 前两个参数同basicAck方法,第三个参数用于标定该消息是否要重新放回队列
      channel.basicNack(deliveryTag,false,true);
      throw new RuntimeException(e);
    }
  }
}

特殊队列

死信队列

  • 死信
    • 当一个消息无法被消费,则成为了死信。
  • 死信产生的原因
    • 拒绝
      • 消费者拒绝接收消息(basicNack/basicReject),并且不把消息重新放入原目标队列(requeue=false)
    • 溢出
      • 队列中消息数量达到限制,根据先进先出原则,队列中最早的消息会变成死信
    • 超时
      • 消息达到超时时间未被消费
  • 死信的处理方式
    • 丢弃
      • 对于不重要的消息直接丢弃,不做处理
    • 入库
      • 把死信写入数据库,之后进行处理
    • 监听
      • 消息变成死信后进入死信队列,并专门设置消费端监听死信队列,做后续处理

要使用死信队列,需要先创建死信队列,再创建正常队列,并且还需要在创建正常队列时指定死信交换机,队列长度,过期时间等信息

备份交换机和死信队列看起来相似,但是前者的设计目的是防止消息因路由失败而丢失,作用在路由阶段。后者设计目的是处理消费失败或延迟的消息,作用在消费阶段。

延迟队列

在rabbitMQ中要使用延迟队列,可以通过死信队列(给正常队列设置超时时间,时间一到就进入死信队列被消费),同时也可以使用插件https://github.com/rabbitmq/rabbitmq-delayed-message-exchange

大数据任务重试:RabbitMQ实现可靠投递 在大数据处理架构中,任务处理通常涉及分布式计算、跨服务调用、海量数据读写等复杂流程。网络延迟、服务瞬时过载、资源竞争等异常场景可能导致任务处理失败。传统的重试机制(如代码内重试逻辑)存在重试策略单一、跨服务重试难追踪、资源消耗不可控等问题。RabbitMQ可靠投递的核心机制(生产者确认、消费者手动确认)死信队列(Dead-Letter Exchange, DLX)的原理与配置指数退避、固定间隔等重试策略的数学模型与代码实现端到端的任务处理链路(生产端发送→消费端处理→失败重试→最终处理) 阅读详情

相关推荐

RabbitMQ消息追踪:排查问题的有效工具

本文旨在全面介绍RabbitMQ消息追踪技术,帮助读者理解消息追踪的重要性,掌握常用的追踪工具和方法,并能够在实际工作中应用这些技术来排查和解决消息队列系统中的问题。本文将首先介绍RabbitMQ和消息追踪的基本概念,然后详细讲解消息追踪的核心原理和工具,接着通过实际案例展示如何应用这些技术,最后讨论相关工具和未来发展趋势。RabbitMQ:一个开源的消息代理和队列服务器,用于在分布式系统中存储和转发消息消息追踪:记录和分析消息在队列系统中的流转过程的技术生产者(Producer)

架构师的AI之路,分享AI应用开发架构的学习与实践。 890

RabbitMQ消费者无故中断问题{writer,send_failed,{error,timeout}}

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34205076的博客 6466

大数据领域 RabbitMQ 的消息延迟处理策略

在大数据应用场景中,消息延迟处理是一个常见且关键的需求。各种延迟处理方案的原理和实现大数据场景下的性能考量高可用性和可靠性保障实际应用案例和最佳实践文章首先介绍RabbitMQ核心概念,然后深入分析延迟处理策略,接着提供实际代码实现和应用场景,最后讨论未来发展趋势。RabbitMQ:开源消息代理软件,实现了高级消息队列协议(AMQP):消息或队列的生存时间,过期后会被自动删除或转发:死信交换机,用于处理被拒绝或过期的消息延迟队列:实现消息延迟投递的特殊队列与云原生技术集成。

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 1000

rabbitMQ消息发送失败处理策略

一、发送失败的三种情况: (1)producter连接mq失败,消息没有发送到mq (2)producter连接mq成功,但是发送到exchange失败 (3)消息发送到exchange成功,但是路由到queue失败; 二、处理策略: (1)异常处理:convertAndSend方法加异常并捕获,失败则发送邮件并保存到数据库中 (2)发送失败处理:这种处理需要先设置rabbitTemplate.setMandatory(true);然后分别对confirmCallback和returnCallback

penn 1万+

绕过卡巴斯基通过RPC控制lsass注入DLL

参考国外的XPN以及3gstudent大佬的文章: https://blog.youkuaiyun.com/xiangshen1990/article/details/104872566 https://gist.github.com/xpn/93f2b75bf086baf2c388b2ddd50fb5d0 原理:正常的ssp扩展(dll)可以加载到lsass进程中去,比如kerberos验证都是通...

2ed 3523

银河麒麟v10-arm版离线安装Portainer

银河麒麟v10-arm版离线安装Portainer

q_hsolucky的博客 3050

记一次rabbitmq生产者的消息无法进入消息队列

的参数位置传递了一个空值,运行起来没有问题。生产者的消息就没法进入消息队列了。但是我不知道为啥不能用我的写法。

weixin_59074080的博客 1107

RocketMq面板访问异常 com.alibaba.fastjson.JSONException: not close json text, token : string

rocketmq JSONException: not close json text, token : string 问题解决

qq_21067307的博客 5573

RabbitMQ中的消息确认ACK机制

我们将消息持久化后,假如消费端出现异常,rabbitmq服务器会将消息缓存到内存,当生产者发送一直发送消息而消费者都没有正常消费时消息就会将这些消息全部保存在内存,当我们的消息过多时,就可能导致rabbitmq服务器内存泄漏, 解决办法:1.开启ack确认机制,2.消费端设置重试机制(默认是三次) 开启之后生产者客户端没有收到消息ack反馈就会认为该消息没有被消费,就会保存到内存,但是设置重试...

liyu121的博客 4649

山东大学FPGA课程实验一 加法器设计

电子设计自动化与FPGA设计,实验一 加法器设计

2503_91283667的博客 869

手把手教你用ADIsimCLK和GUI搞定HMC7044时钟配置(附避坑指南)

本文详细解析了HMC7044时钟芯片的配置方法,通过ADIsimCLK和HMC7044 Configuration GUI工具,从频率规划到硬件验证全流程实战演示。特别针对PLL模式选择、分频链配置等易错环节,提供量产验证的配置模板和实测数据,帮助工程师快速掌握高性能时钟解决方案。

weixin_30755393的博客 794

rabbitmq如何保证消息的可靠性

rabbitmq如何保证消息的可靠性

林隐的博客 1908

基于JAVA的GB28181实现之SIP服务核心组件解析

本文深入解析了基于JAVA的GB28181标准中SIP服务的核心组件实现,包括协议栈选择、消息处理引擎、事务管理器等关键技术点。通过实战案例分享海康威视、大华设备的特殊处理技巧,并提供性能优化和常见问题排查指南,帮助开发者高效构建稳定的视频监控系统。

weixin_30892037的博客 263

RabbitMQ速通--01消息队列概述与安装

消息队列基本概念、核心特性、常见消息队列模式、docker安装RabbitMQ

bugnotfound的博客 799

硬件知识点-----SPI串联电阻、振铃、过冲

电阻取值,没有公式,一被传输线的特征阻抗为50欧姆左右,而TTL电路输出电阻大桃为13欧姆左右,在源端串一个33姆,大致和50相当,这样就可以柳制从终端反射回来的倍号,防止再次反射。传输时间tp=L/V,其中L是导线长度,V是电磁波在电路板中的传输速度V=C/sqrDk,其中Dk是光速衰减因子,对于电路板而言是铜线,Dk=4电磁波在电路板中的速度都是慢于光速的。实际上串联多大的电阻与传输线的阻抗有关,为了保证阻抗的连续性,如果传输线的特性阻抗 Z0与驱动源的输出阻抗 Zd不匹配,会引发信号的反射。

贾saisai的博客 2714

基于 ESP32 的分布式光伏微电网智能监控系统设计与实现

设备 / 模块连接 ESP32 引脚备注I2C 总线(SDA)GPIO21所有 I2C 设备共用I2C 总线(SCL)GPIO22所有 I2C 设备共用DS18B20(单总线)GPIO18单总线通信,需外接 4.7K 上拉电阻有源蜂鸣器GPIO19低电平触发,串联 100Ω 限流电阻ESP32 供电5V/GND由 LM2596 输出 5V 供电,或直接 USB 供电(调试阶段)INA219(光伏)光伏阵列正负极接 INA219 的 VIN+/VIN-

weixin_42300449的博客 303

一篇文章带你搞定面试RabbitMq

一篇文章带你搞懂RabbitMQ

2302_76222359的博客 1573

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

RabbitMQ学习笔记(一)

RabbitMQ 简介 MQ 消息队列,上承生产者,下接消费者。从生产者侧获取消息,然后将消息转发给消费者。 由此可见,MQ必须具有两个属性:消息的缓存和路由。 此外,由于MQ的存在,使得原来消息的一次投递(生产者 --- > 消费者)变成了两次投递(生产者 ---> MQ ---> 消费者)。由此,MQ就需要考虑消息投递的可靠性问题,并由此引申出消息的防重发、防丢失问题。 ...

感谢你的关注~~~~ღ( ´・ᴗ・` ) 534

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

RabbitMQ面试题总结

DLX,全称为,死信交换器,死信邮箱。当消息在一个队列中变成死信 () 之后,它能被重新发送到另一个交换器中,这个交换器就是 DLX,绑定 DLX 的队列就称之为死信队列。导致的死信的几种原因消息被拒() 且。消息 TTL 过期。队列满了,无法再添加。延迟队列指的是存储对应的延迟消息,消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

csdnuu123的博客 797

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

RabbitMQ相关问题

RabbitMQ核心概念与工作模式摘要:RabbitMQ作为开源消息代理,包含生产者、消费者、队列、交换机和虚拟主机等核心组件。支持简单模式、工作队列模式、广播模式、路由模式和主题模式五种工作模式,分别适用于不同消息分发场景。为确保消息可靠性,提供生产端确认机制、服务端持久化和事务处理、消费端手动确认等措施。针对消息重复问题,建议采用唯一消息ID和分布式锁方案。死信队列用于处理被拒、过期或超限的消息,通过配置死信交换机实现特殊处理。本文系统介绍了RabbitMQ的核心概念及典型应用方案。

susadia288263的博客 1417

rabbitMQ 精髓

一、简介 1、消息中间件:利用高效可靠的消息传递机制进行和平台不耦合的数据交流,利用数据通信来进行分布式系统的集成。由JMS发展而来。 2、rabbitMQ:采用Erlang语言实现AMQP的消息中间件,用在分布式系统中存储转发消息。整体模型架构如下: producer:生产者,发送消息的那方,消息包含消息体(payload)和标签 Consumer:消费者,接收消息的那方,只得消...

真是呆子啊的博客 424

RabbitMQ 简介

为什么80%的码农都做不了架构师?>>> ...

weixin_34068198的博客 304

RabbitMQ可靠投递与消息幂等性实战指南

消息队列作为分布式系统解耦的核心组件,其可靠性设计直接影响系统稳定性。RabbitMQ通过AMQP协议实现生产者确认、消息持久化和消费者手动确认三重保障机制,确保消息不丢失。在电商秒杀、金融支付等高并发场景中,结合死信队列处理异常消息,配合TTL+DLX实现延迟队列功能,能有效解决订单超时等业务需求。针对网络抖动导致的消息重复问题,采用Redis分布式锁或消息指纹等方案实现消费幂等性。本文通过生产者确认模式代码示例和死信队列配置演示,展现RabbitMQ在保证消息可靠投递与精确一次消费方面的最佳实践。

weixin_33883104的博客 216

死信队列如何帮助保证消息队列的可靠性

摘要:死信队列(DLQ)是消息队列的可靠性保障机制,用于存储无法正常消费的消息。消息因过期、队列满或消费失败时会被转入DLQ。其核心作用包括防止消息丢失、辅助问题排查以及实现延迟任务处理。以RabbitMQ为例,通过配置死信交换机(DLX)、死信队列及源队列参数(x-dead-letter-exchange等)即可实现。当源队列消息满足特定条件时,会自动路由到DLQ,开发者可对死信消息进行后续处理或分析。这种机制有效提升了消息系统的容错能力和可靠性。

qq_46130027的博客 327

从零设计一个RabbitMQ死信队列:处理失败消息的完整方案

本文详细介绍了从零设计RabbitMQ死信队列的完整方案,用于优雅处理分布式系统中的失败消息。通过结合死信交换机、TTL延迟队列和手动确认机制,实现消息的自动重试、异常隔离与分级处理,有效解决支付回调、订单同步等场景下的消息可靠性问题,并提供了生产环境的最佳实践与监控策略。

o5p6q的博客 147
上一篇: RabbitMQ速通--03整合SpringBoot
sisyphoslee
博客等级 码龄7年 942粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值