RabbitMQ高级特性

学习RabbitMQ高级特性 1、消息可靠性投递 【confirm 确认模式、return 退回模式】 2、Consumer ACK 【acknowledge】 3、消费端限流 【prefetch】 4、TTL过期时间 【time to live】 5、死信队列 【Dead Letter Exchange】 6、延迟队列 【rabbitmq-delayed-message-exchange】 7、优先级队列 【x-max-priority】 阅读详情

目录

1.消息可靠投递

1.1生产方确认模式

1.2生产方退回模式

2.Consumer ACK

3.消费端限流

4.TTL

4.1消息过期时间

4.2队列过期时间

5.死信队列

6.延迟队列

7.消息追踪,日志监控

8.消息可靠性保障

8.1消息补偿机制

8.2.消息幂等性保障

9.集群搭建


1.消息可靠投递

在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。

  1. lconfirm 确认模式
  2. lreturn  退回模式

rabbitmq 整个消息投递的路径为:

producer--->rabbitmq broker--->exchange--->queue--->consumer

  1. 消息从 producer 到 exchange 则会返回一个 confirmCallback 。
  2. 消息从 exchange-->queue 投递失败则会返回一个 returnCallback 。

我们将利用这两个 callback 控制消息的可靠性投递

1.1生产方确认模式

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/spring/spring-rabbitmq.xml")
public class ProducerTest {
    @Autowired
    private RabbitTemplate rabbitTemplatel;

    /**
     * 确认模式
     *  1.确认模式开启 connectionFactory publisher-confirms="true"
     *  2.定义一个confirms 回调函数
     */
    @Test
    public void testHelloWord(){

        //定义回调
        rabbitTemplatel.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *
             * @param correlationData 配置信息
             * @param b 交换机是否收到了消息, true success
             * @param s 失败原因
             */
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if(b){
                    System.out.println("接受成功消息");
                }else{
                    System.out.println("接受消息失败:" +s);
                }
                System.out.println("回调函数被执行了");
            }
        });
        rabbitTemplatel.convertAndSend("test_confirm_exchange","spring","message test_confirm_exchange");
    }
}

1.2生产方退回模式

  /**
     * 回退模式:当交换机路由到队列失败后
     *  1.回退模式开启 connectionFactory  publisher-returns="true"
     *  2.定义一个return 回调函数
     *  3.设置一个交换机处理消息的模式
     *      1.消息丢弃
     *      2.返回消息发送方
     */
    @Test
    public void testReturn(){
        //设置交换机处理失败模式
        rabbitTemplatel.setMandatory(true);
        //定义回调
        rabbitTemplatel.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             *
             * @param message 消息对象
             * @param i 错误码
             * @param s 错误信息
             * @param s1 交换机
             * @param s2 路由键
             */
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.out.println("return 执行了");
            }
        });
        rabbitTemplatel.convertAndSend("test_confirm_exchange","spring","message test_confirm_exchange");
    }

2.Consumer ACK

ACK 消费端收到消息的确认方式

  • 自动确认:acknowledge="none"
  • 手动确认:acknowledge="manual"
  • 根据异常情况确认:acknowledge="auto"

其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应 message 从 RabbitMQ 的消息缓存中移除。但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAck(),手动签收,如果出现异常,则调用channel.basicNack()方法,让其自动重新发送消息。


import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

/**
 * Consumer ACK机制:
 *  1. 设置手动签收。acknowledge="manual"
 *  2. 让监听器类实现ChannelAwareMessageListener接口
 *  3. 如果消息成功处理,则调用channel的 basicAck()签收
 *  4. 如果消息处理失败,则调用channel的basicNack()拒绝签收,broker重新发送给consumer
 *
 *
 */

@Component
public class AckListener implements ChannelAwareMessageListener {

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try {
            //1.接收转换消息
            System.out.println(new String(message.getBody()));
            //2. 处理业务逻辑
            System.out.println("处理业务逻辑...");
            //int i = 3/0;//出现错误
            //3. 手动签收
            channel.basicAck(deliveryTag,true);
        } catch (Exception e) {
            //e.printStackTrace();

            //4.拒绝签收
            /*
            第三个参数:requeue:重回队列。如果设置为true,则消息重新回到queue,broker会重新发送该消息给消费端
             */
            channel.basicNack(deliveryTag,true,true);
            //channel.basicReject(deliveryTag,true);
        }
    }
}

3.消费端限流

package cn.bufanli.rabbit.listener;


import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

/**
 *  consumer 限流
 *  1.确保ack机制为手动确认
 *  2.配置属性 listener-container prefetch="1"
 *   perfetch = 1,表示消费端每次从mq拉去一条消息来消费,直到手动确认消费完毕后,才会继续拉去下一条消息。
 *
 */

@Component
public class QosListener implements ChannelAwareMessageListener{
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        Thread.sleep(1000);
        //1.获取消息
        System.out.println(new String(message.getBody()));
        //2. 处理业务逻辑
        //3. 签收
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);

    }

}

4.TTL


 

全称 Time To Live(存活时间/过期时间)当消息到达存活时间后,还没有被消费,会被自动清除

RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间

设置队列过期时间使用参数:x-message-ttl,单位:ms(毫秒),会对整个队列消息统一过期

设置消息过期时间使用参数:expiration。单位:ms(毫秒),当该消息在队列头部时(消费时),会单独判断这一消息是否过期。

如果两者都进行了设置,以时间短的为准。

4.1消息过期时间

 //消息处理对象,设置一些消息的参数消息
         MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
             public Message postProcessMessage(Message message) throws AmqpException {
                 //1.设置message的消息过期时间
                 message.getMessageProperties().setExpiration("5000");
                 return message;
             }
         };
         rabbitTemplatel.convertAndSend("test_exchange_ttl"
                 ,"ttl.hehe","message test_ttl_exchange" ,messagePostProcessor);

 

4.2队列过期时间

    <!--ttl-->
    <rabbit:queue name="test_queue_ttl" id="test_queue_ttl">
        <!--设置q的参数-->
        <rabbit:queue-arguments>
            <entry key="x-message-ttl" value="10000" value-type="java.lang.Integer"></entry>
        </rabbit:queue-arguments>
    </rabbit:queue>

5.死信队列

死信队列,英文缩写:DLX  。Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。

消息成为死信的三种情况:

1. 队列消息长度到达限制 ;
2. 消费者拒接消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列 ,requeue=false ;
3. 原队列存在消息过期设置,消息到达超时时间未被消费

 

队列绑定死信交换机:

给队列设置参数 : x-dead-letter-exchange 和 x-dead-letter-routing-key
 
 <!--死信队列
        1.声明正常的队列(test_queue_dlx) 和 交换机(test_exchange_dlx)
        2.声明死信队列 (queue_dlx)和交换机(test_exchange_dlx)
        3.正常队列绑定死信交换机
            设置两个参数
                x-dead-letter-exchange 队列交换机名称
                x-dead-letter-routing-key 死信交换机使用的routingkey
        4.设置过期时间、最大长度                
        -->
    <rabbit:queue name="test_queue_dlx" id="test_queue_dlx">
        <!--正常队列绑定死信交换机-->
        <rabbit:queue-arguments>
            <!--队列交换机名称-->
            <entry key="x-dead-letter-exchange" value="exchange_dlx" />
            <entry key="x-dead-letter-routing-key" value="dlx.xx" />
            <!--设置队列的过期时间 毫秒 Integer类型-->
            <entry key="x-message-ttl" value="10000" value-type="java.lang.Integer"/>
            <!--设置队列的最大长度 条 Integer类型-->
            <entry key="x-max-length" value="10" value-type="java.lang.Integer"/>
        </rabbit:queue-arguments>
    </rabbit:queue>
    <rabbit:topic-exchange name="test_exchange_dlx">
        <rabbit:bindings>
            <rabbit:binding pattern="test.dlx.#" queue="test_queue_dlx"/>
        </rabbit:bindings>
    </rabbit:topic-exchange>
    <!--2.声明死信队列 (queue_dlx)和交换机(test_exchange_dlx)-->
    <rabbit:queue name="queue_dlx" id="queue_dlx">

    </rabbit:queue>
    <rabbit:topic-exchange name="exchange_dlx">
        <rabbit:bindings>
            <rabbit:binding pattern="dlx.#" queue="queue_dlx"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>
1. 死信交换机和死信队列和普通的没有区别


2. 当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列


3. 消息成为死信的三种情况:

    1. 队列消息长度到达限制;

    2. 消费者拒接消费消息,并且不重回队列;
    
    3. 原队列存在消息过期设置,消息到达超时时间未被消费;

6.延迟队列

1. 延迟队列 指消息进入队列后,可以被延迟一定时间,再进行消费。

2. RabbitMQ没有提供延迟队列功能,但是可以使用 : TTL + DLX 来实现延迟队列效果。

 

需求:

1. 下单后,30分钟未支付,取消订单,回滚库存。

2. 新用户注册成功7天后,发送短信问候。

实现方式:

1. 定时器

2. 延迟队列

在RabbitMQ中可以使用:TTL+死信队列 组合实现延迟队列的效果。

 

 

7.消息追踪,日志监控

在RabbitMQ中可以使用Firehose和rabbitmq_tracing插件功能来实现消息追踪。

在使用任何消息中间件的过程中,难免会出现某条消息异常丢失的情况。对于RabbitMQ而言,可能是因为生产者或消费者与RabbitMQ断开了连接,而它们与RabbitMQ又采用了不同的确认机制;也有可能是因为交换器与队列之间不同的转发策略;甚至是交换器并没有与任何队列进行绑定,生产者又不感知或者没有采取相应的措施;另外RabbitMQ本身的集群策略也可能导致消息的丢失。这个时候就需要有一个较好的机制跟踪记录消息的投递过程,以此协助开发和运维人员进行问题的定位。

 

firehose的机制是将生产者投递给rabbitmq的消息,rabbitmq投递给消费者的消息按照指定的格式发送到默认的exchange上。这个默认的exchange的名称为amq.rabbitmq.trace,它是一个topic类型的exchange。发送到这个exchange上的消息的routing key为 publish.exchangename 和 deliver.queuename。其中exchangename和queuename为实际exchange和queue的名称,分别对应生产者投递到exchange的消息,和消费者从queue上获取的消息。

注意:打开 trace 会影响消息写入功能,适当打开后请关闭。

  • rabbitmqctl trace_on:开启Firehose命令
  • rabbitmqctl trace_off:关闭Firehose命令

 

rabbitmq_tracing和Firehose在实现上如出一辙,只不过rabbitmq_tracing的方式比Firehose多了一层GUI的包装,更容易使用和管理。

启用插件:rabbitmq-plugins enable rabbitmq_tracing

设置-》#号符号会把所有的的消息都存日志 add trace 即可

添加日志插件

 

8.消息可靠性保障

8.1消息补偿机制

 

8.2.消息幂等性保障

 

幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

 

在MQ中指,消费多条相同的消息,得到与消费该消息一次相同的结果

9.集群搭建

待续

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

RabbitMQ 高级特性 延迟队列是⼀个特殊的队列,消息发送之后,并不⽴即给消费者,⽽是等待特定的时间,才发送给消费者.延迟队列的应⽤场景有很多,⽐如:1.订单在⼗分钟内未⽀付⾃动取消2.⽤户注册成功后,3天后发调查问卷3.⽤户发起退款,24⼩时后商家未处理,则默认同意,⾃动退款但RabbitMQ本⾝并没直接实现延迟队列,通常有两种⽅法:1.TTL+死信队列组合的⽅式2.使⽤官⽅提供的延迟插件实现延迟功能⼆者对比:1.基于死信实现的延迟队列a.优点:1)灵活不需要额外的插件⽀持。 阅读详情

相关推荐

Excel数据清洗实战:8个必学函数搞定90%的脏数据问题(附案例)

本文通过一个完整的销售数据清洗案例,详细讲解了如何组合使用TRIM、CLEAN、SUBSTITUTE等8个核心Excel函数,构建自动化清洗流水线,高效解决日常办公中90%的脏数据问题,从而将时间留给更有价值的分析工作。

weixin_29215391的博客 582

08 RabbitMQ高级特性

1. RabbitMQ 高级特性 1.1 消息可靠性投递 在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。 confirm 确认模式 return 退回模式 rabbitmq 整个消息投递的路径为: ​ producer —> rabbitmq broker —> e...

痞子王的博客 1102

别再为授权费头疼了!手把手教你免授权搞定西门子、马扎克等12种主流数控机床的数据采集

本文提供了一套免授权采集西门子、马扎克等12种主流数控机床数据的实战指南,帮助中小型机加工车间节省80%以上的采集成本。通过TCP/UDP协议逆向工程和跨平台数据整合,实现经济、灵活且可持续的数据采集方案,涵盖设备兼容性处理、数据频率优化等关键问题。

weixin_26873711的博客 707

RabbitMQ:Queue的介绍和使用

1.声明 当前内容用于本人学习和使用当前的Queue,当前内容为RabbitMQ中对Queue的介绍 当前内容来源:RabbitMQ中的Queue 2.Queue的官方介绍 首先先分析以下前面的Queue的使用,其实这个东西就是一个队列,一个存储消息的队列,并且可以持久化,而且这个队列中的消息可以被消费,如果出现死信则是死信队列,死信队列也是可以被处理的 接下来就是官方介绍 Queues in the AMQP 0-9-1 model are very similar to queues in other

编程学习者的博客 7649

SOC Boot学习(二)——JTAG Debug介绍

JTAG(Joint Test Action Group ,联合测试行动小组 ) 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。JTAG 技术是一种嵌入式调试技术,它在芯片内部封装了专门的测试电路 TAP ( Test Access Port ,测试访问口),通过专用的 JTAG 测试工具对内部节点进行测试。如今大多数比较复杂的器件都支持 JTAG 协议,如 ARM 、 DSP 、 FPGA 器件等。

yttt的博客 1605

LVGL 源码分析大全

LVGL 是一款流行的免费和开源嵌入式图形库,为纯C的轻量级GUI框架,支持framebuffer直接渲染图层,因此LVGL能更容易为 MCU、MPU等显示设备开发漂亮的UI。可视化的 UI 编辑器官方上有推荐使用工具。当然,也可以选择 NXP(恩智浦半导体) 提供的工具。........................

Bigan(安)的博客 1万+

Rabbitmq的过期时间

过期时间TTL 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取;过了之后消息将自动被删除。RabbitMQ可以对消息和队列设置TTL。目前有两种方法可以设置。 第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。 第二种方法是对消息进行单独设置,每条消息TTL可以不同。 如果上述两种方法同时使用,则消息的过期时间以两者之间TTL较小的那个数...

qq_29860591的博客 1193

机器学习实战7-基于机器学习算法预测相亲成功率

大家好,我是微学AI,今天给大家介绍一下机器学习实战7-基于机器学习算法预测相亲成功率,随着社会的发展,大家都忙于事业,对自己的终身大事就耽搁了,相亲是一种传统的寻找伴侣的方式,随着时代的发展,相亲的方式也在不断地改变。在这个过程中,了解相亲双方的信息以及预测相亲是否成功变得越来越重要。本文将介绍如何使用随机森林算法对相亲成功进行预测,通过分析男女双方的房子、车子、长相、家庭条件、父母情况、生活习惯、学历、性格、兴趣等因素,来预测相亲是否成功。

微学AI的博客 3028

RabbitMQ之Queue(队列)属性解读

基本上所有的操作都落在master上,那么如果这些queues的master都落在个别的服务节点上,而其他的节点又很空闲,这样就无法做到负载均衡,那么势必会影响性能;队列类型x-queue-mode=lazy懒队列,在磁盘上尽可能多地保留消息以减少RAM使用,如果未设置,则队列将保留内存缓存以尽可能快地传递消息;队列所能容下消息的最大长度,当超出长度后,新消息将会覆盖最前面的消息,类似于Redis的LRU算法;: 是否自动删除,如果为true,当没有消费者连接到这个队列的时候,队列会自动删除;

一个菜鸡的博客 2069

零基础学GPU KMD--8. 内存管理:GPU 显存与系统内存的协同​8.1 显存分配策略:GEM / TTM 原理

支持 VRAM、GTT(Graphics Translation Table)、SYSTEM 内存的动态迁移与缓存管理。:若缓冲区在 SYSTEM,TTM 分配 GTT 条目并建立页表映射,使 GPU 可直接访问。:系统内存中预留给 GPU 直接访问的区域,通过 GPU 的 MMU 做地址翻译。你需要我继续展开这一部分吗?​ 为复杂离散 GPU 设计,应对大容量 VRAM、多内存域、显存迁移等问题。:重量级、功能全,适合大容量、多内存域的离散 GPU,强调显存迁移与统一管理。

amy_mhd的博客 185

家用扫地机器人实物拆解报告-从顶盖到每一颗螺丝 · 逐层拆解旗舰扫拖一体机器人

2026年旗舰扫拖机器人拆解报告:采用D形机身设计,主机重4.5kg,基站重12kg。核心配置包括RK3588S+STM32H743双处理器、8颗21700电池、LDS激光雷达和双摄像头+结构光导航系统。创新设计亮点:锥形滚刷自动排毛发、活水循环拖地系统、基站集成450W强力集尘和自动上下水模块(带三重防漏保护)。整机采用模块化设计,关键部件均支持快速更换,在密封性、防呆设计和降本增效方面展现出成熟的工程智慧。

智能硬件研发,欢迎交流 515

RabbitMQ(二)

(1) MQ的概念 Message Queue :消息队列,存放消息的一个容器(先进先出) (2)MQ的优点 解耦 、 异步提速 、 削峰填谷 (3)MQ的缺点 可用性减弱 、复杂性提供、处理一致性 MQ是需要成本的,适合的地方使用。 (4)MQ的实现 RabbitMQ(erlang AMQP协议) ActiveMQ(java JMS接口规范) RocketMQ(java) Kafka(大数据)...

种一颗十年前的树 214

SPAD IMX479规格_VOP

对于VOP的定义,很多人可能是不理解这一路的供电,实际上这一路供电是非常重要的,这是给器件SPAD供电,决定SPAD是否work,在大部分的paper以及大部分公司,基本都是叫VOP,名称是SPAD breakdown voltage power supply,严格意义上叫Operating Voltage,工作电压。当然有些公司也有一些其他叫法就不提了。其实大家可以明显的看出,典型值-20.5没有发生变化,市面上绝大多数VOP的典型值也都是在-20V这边。

致力于lidar应用开发 701

rabbitmq——高级特性

rabbitmq,高级特性 目录 rabbitmq,高级特性 1.消息如何保障100% 的投递成功?        1.1 自定义消费者    1.2 消息的ack与重回队列    1.3 消息的限流    1.4 TTL消息    1.5 死信队列 2.幂等性概念详解 消费端,幂等性保障; (1)唯一id +  指纹码 机制, 利用数据库主键去重;  (2) 利用redis 的原...

小智的博客 3266

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【RabbitMQ】 RabbitMQ高级特性(二)

RabbitMQ高级特性

2403_87459748的博客 2312

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【RabbitMQ】高级特性

本文将介绍一些RabbitMQ的重要特性。本文是使用的Spring整合RabbitMQ环境。

p_fly的博客 1663

【RabbitMQ】 RabbitMQ高级特性

生产者首先发送条消息,然后经过交换器(normal_exchange)顺利地存储到队列(normal_queue)中. 由于队列normal_queue设置了过期时间为10s, 在这10s内没有消费者消费这条消息, 那么判定这条消息过期. 由于设置了DLX, 过期之时, 消息会被丢给交换器(dlx_exchange)中, 这时根据RoutingKey匹配, 找到匹配的队列(dlx_queue), 最后消息被存储在queue.dlx这个死信队列中.死信队列接收到消息: ttl test 10s…

2501_92289558的博客 892
上一篇: MQ的优势和劣势和RabbitMQ基本模式案例
下一篇: FUNCTION cr_debug.ENTER_MODULE2 does not exist
别浪呀
博客等级 码龄8年 1万+粉丝 260原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值