RabbitMQ 高级特性实战(基于 Spring Boot)

125 阅读4分钟

沉默是金,总会发光

大家好,我是沉默

很多人用 RabbitMQ,只知道拿来“发消息”,其实它背后的高级特性才是真正撑起高可用、高并发系统的筋骨。

本文将带你基于 Spring Boot 实战 6 大核心特性,从削峰填谷的限流,到按优先级发货的队列处理,干货满满,一套搞定!

**-**01-

消费端限流

限流就是削峰填谷的“节流阀”

假设你的系统 QPS 峰值只能撑 1000,请求量一口气飙到 5000,直接炸。
加入 MQ,消息先入队再慢慢处理,设置消费端限速为 1000/QPS,虽然消息积压了,但系统活着。

目的:保护消费者,不让它被突发流量压垮。

实现方式:配置 + 手动签收 + 限速

开启限流的前提:必须手动签收,否则自动签收=全部接收=根本没限流。

YML 配置:

spring:
  rabbitmq:
    host: 192.168.0.162
    port: 5672
    username: zzzzzt
    password: zzzzzt
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: manual  # 手动签收
        prefetch: 5               # 每次最多拉5条消息

消费者代码:

@Component
public class QosConsumer {
  @RabbitListener(queues = "my_queue")
  public void listenMessage(Message message, Channel channel) throws IOException, InterruptedException {
    System.out.println(new String(message.getBody()));
    Thread.sleep(3000); // 模拟业务处理
    channel.basicAck(message.getMessageProperties().getDeliveryTag(), true); // 手动签收
  }
}

**-**02-

不公平分发

多个消费者监听同一个队列,RabbitMQ 默认轮询分发

但现实中,总有“优等生”和“慢吞吞”。
这时候就需要“不公平分发”机制,让谁处理快谁先吃!

实现方式:改 prefetch = 1!

spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual
        prefetch: 1  # 每次拉1条消息,谁快谁拉

**-**03-

消息存活时间(TTL)

“延迟处理”、“定时关闭未支付订单”场景常用 TTL。

RabbitMQ 支持两种 TTL 方式:

  1. 整队设置(全员定时清理)

  2. 单条设置(只炸这一条)

示例代码:

整队 TTL:

@Bean
public Queue getMessageQueue2() {
    return QueueBuilder
            .durable("bootQueue2")
            .ttl(10000// 每条消息存活10秒
            .build();
}

单条 TTL:

@Test
public void testSendMessage() {
    MessageProperties props = new MessageProperties();
    props.setExpiration("10000"); // 设置10秒TTL
    Message message = new Message("Hello TTL".getBytes(), props);
    rabbitTemplate.convertAndSend("my_topic_exchange""my_routing", message);
}

**-**04-

优先级队列

大客户(比如 Apple、京东)订单必须先处理,小客户稍等。

这时候就需要 RabbitMQ 的 优先级队列(Priority Queue) 上场。

实现方式:

定义优先级队列:

@Bean
public Queue priorityQueue() {
    return QueueBuilder
            .durable("priority_queue")
            .maxPriority(10// 建议不超过10
            .build();
}

发送优先级消息:

@Test
public void testPriority() {
    for (int i = 0; i < 10; i++) {
        if (i == 5) {
            MessageProperties props = new MessageProperties();
            props.setPriority(9);
            Message msg = new Message(("VIP订单" + i).getBytes(), props);
            rabbitTemplate.convertAndSend("priority_exchange""my_routing", msg);
        } else {
            rabbitTemplate.convertAndSend("priority_exchange""my_routing""普通订单" + i);
        }
    }
}

**-**05-

死信队列(DLX)

什么是死信?

消息“死”了 = 被拒收 or 到期未处理 or 队列爆满。

这些消息不能直接丢,应该转送到死信交换机(DLX),转发到死信队列 Dead Queue里去,做二次处理。

实战代码:

普通队列绑定死信交换机:

@Bean
public Queue normalQueue() {
    return QueueBuilder.durable("normal_queue")
            .deadLetterExchange("dead_exchange")
            .deadLetterRoutingKey("dead_routing")
            .ttl(10000)
            .maxLength(10)
            .build();
}

模拟死信:

@Test
public void testDlx() {
    // 消息过期变死信
    rabbitTemplate.convertAndSend("normal_exchange""my_routing""过期死信");
    // 队列满了变死信
    for (int i = 0; i < 15; i++) {
        rabbitTemplate.convertAndSend("normal_exchange""my_routing""满了死信" + i);
    }
    // 拒签死信
    rabbitTemplate.convertAndSend("normal_exchange""my_routing""拒签死信");
}

消费者拒签示例:

@Component
public class DlxConsumer {
    @RabbitListener(queues = "normal_queue")
    public void listenMessage(Message message, Channel channel) throws IOException {
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), truefalse); // 拒签且不重回队列
    }
}

**-**06-

延迟队列

“订单30分钟未支付自动取消”,RabbitMQ 本身没延迟队列,但我们可以用 TTL + 死信机制组合变相实现。

实现方式:

@Bean
public Queue orderDelayQueue() {
    return QueueBuilder.durable("order_delay_queue")
            .ttl(1800000// 30分钟
            .deadLetterExchange("order_dlx_exchange")
            .deadLetterRoutingKey("order_cancel_routing")
            .build();
}

然后消费 order_cancel_queue 即可实现“延迟取消订单”。

总结:RabbitMQ 高级特性速览表

特性应用场景核心机制
消费端限流削峰填谷手动签收 + prefetch 限制
不公平分发谁快谁多prefetch = 1
消息存活时间 TTL定时处理/过期丢弃队列 TTL/消息 TTL
优先级队列大客户优先maxPriority + message.setPriority
死信队列异常消息“转院”DLX + Routing Key
延迟队列定时取消/延迟处理任务TTL + 死信组合

说说你最想用哪一个特性?遇到过哪些场景?

热门文章

一套能保命的高并发实战指南

架构师必备:用 AI 快速生成架构图

**-**07-

粉丝福利

我这里创建一个程序员成长&副业交流群,和一群志同道合的小伙伴,一起聚焦自身发展,可以聊:技术成长与职业规划,分享路线图、面试经验和效率工具,探讨多种副业变现路径,从写作课程到私活接单,主题活动、打卡挑战和项目组队,让志同道合的伙伴互帮互助、共同进步。如果你对这个特别的群,感兴趣的,可以加一下,微信通过后会拉你入群,但是任何人在群里打任何广告,都会被我T掉。