Tavio's blog Tavio's blog
首页
  • JVM底层原理
  • 邪恶多线程
  • MyBatis底层原理
  • Spring底层原理
  • MySQL的优化之路
  • ClickHouse的高性能
  • Redis的快速查询
  • RabbitMQ的生产
  • Kafka的高吞吐量
  • ES的入门到入坑
  • MySQL自增ID主键空洞
  • 前端实现长整型排序
  • MySQL无感换表
  • Redis延时双删
  • 高并发秒杀优惠卷
  • AOP无侵入式告警
  • 长短链接跳转
  • 订单超时取消
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Tavio Zhang

努力学习的小码喽
首页
  • JVM底层原理
  • 邪恶多线程
  • MyBatis底层原理
  • Spring底层原理
  • MySQL的优化之路
  • ClickHouse的高性能
  • Redis的快速查询
  • RabbitMQ的生产
  • Kafka的高吞吐量
  • ES的入门到入坑
  • MySQL自增ID主键空洞
  • 前端实现长整型排序
  • MySQL无感换表
  • Redis延时双删
  • 高并发秒杀优惠卷
  • AOP无侵入式告警
  • 长短链接跳转
  • 订单超时取消
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • RabbitMQ概念扫盲
    • 一、RabbitMQ核心组件:从快递流程理解
      • 1.1 生产者(Producer)
      • 1.2 交换机(Exchange)
      • 1.3 路由键(Routing Key)
      • 1.4 绑定(Binding)
      • 1.5 队列(Queue)
      • 1.6 消费者(Consumer)
      • 1.7 消息流转完整流程
    • 二、交换机类型:不同场景的路由策略
      • 2.1 Direct Exchange(直连交换机)
      • 2.2 Topic Exchange(主题交换机)
      • 2.3 Fanout Exchange(扇形交换机)
      • 2.4 Headers Exchange(头交换机)
    • 三、高级特性:确保消息可靠与高效
      • 3.1 负载均衡:prefetch配置
      • 3.2 消息持久化
      • 3.3 消息确认机制
    • 总结
  • RabbitMQ集群
  • RabbitMQ生产者可靠性
  • RabbitMQ消息持久化
  • RabbitMQ消费者可靠性
  • Rabbit延时消息
  • 《RabbitMQ》笔记
Tavio
2023-06-18
目录

RabbitMQ概念扫盲

在分布式系统中,服务间的通信往往面临三大挑战:

  • 耦合度高:同步调用导致服务间相互依赖,一方故障可能引发连锁反应;
  • 流量峰值:突发请求(如秒杀)可能压垮下游服务;
  • 异步需求:非核心流程(如日志记录、消息通知)无需阻塞主流程。

RabbitMQ作为一款成熟的消息队列(MQ)中间件,通过"生产者-交换机-队列-消费者"的异步通信模式,完美解决了上述问题。它就像一个"分布式快递系统",让消息在服务间高效、可靠地流转。

# 一、RabbitMQ核心组件:从快递流程理解

# 1.1 生产者(Producer)

角色定位:消息的创建者,负责将业务数据封装为消息并发送到RabbitMQ。 类比场景:网购时的商家,打包商品并交给快递员。 核心特性:

  • 只负责"发送消息",不关心消息被谁处理、如何处理;
  • 发送前需指定消息的"目的地标识"(路由键)。

代码示例(Spring AMQP):

@Service
public class OrderProducer {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 发送订单消息
    public void sendOrderMsg(Order order) {
        String exchangeName = "order.exchange";
        String routingKey = "order.create"; // 路由键:标识消息类型
        rabbitTemplate.convertAndSend(exchangeName, routingKey, order);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 1.2 交换机(Exchange)

角色定位:消息的"中转站",接收生产者的消息并按规则转发到队列。 类比场景:快递中转站,根据地址将包裹分到不同区域线路。 核心特性:

  • 不存储消息,仅负责转发;
  • 必须与队列绑定(通过绑定规则),否则消息会被丢弃;
  • 转发规则由交换机类型决定(后文详细说明)。

# 1.3 路由键(Routing Key)

角色定位:消息的"地址标签",用于交换机判断消息应转发到哪些队列。 类比场景:快递单上的详细地址(如"北京市朝阳区XX街道")。 使用说明:

  • 由生产者在发送消息时指定(字符串格式,可包含.分隔符,如order.pay.success);
  • 交换机通过路由键与"绑定键"(队列与交换机的绑定规则)匹配,决定转发逻辑。

# 1.4 绑定(Binding)

角色定位:交换机与队列之间的"路由规则",定义了两者的关联关系。 类比场景:快递站的"路线配置"(如"所有发往朝阳区的快递走XX线路")。 核心要素:

  • 绑定键(Binding Key):规则表达式,与路由键匹配;
  • 匹配逻辑由交换机类型决定(如Direct需完全匹配,Topic支持通配符)。

代码示例(绑定配置):

@Configuration
public class RabbitConfig {
    // 声明交换机
    @Bean
    public DirectExchange orderExchange() {
        // 参数:交换机名称、是否持久化、是否自动删除
        return new DirectExchange("order.exchange", true, false);
    }

    // 声明队列
    @Bean
    public Queue orderQueue() {
        return QueueBuilder.durable("order.queue") // 持久化队列
                          .build();
    }

    // 绑定交换机与队列(绑定键为"order.create")
    @Bean
    public Binding orderBinding(DirectExchange orderExchange, Queue orderQueue) {
        return BindingBuilder.bind(orderQueue)
                            .to(orderExchange)
                            .with("order.create"); // 绑定键
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 1.5 队列(Queue)

角色定位:消息的"存储容器",是RabbitMQ中唯一持久化消息的组件。 类比场景:小区的菜鸟驿站,暂存快递等待用户取件。 核心特性:

特性 说明 适用场景
持久化 队列元数据(名称、配置)和消息内容在RabbitMQ重启后不丢失 核心业务消息(如订单、支付)
排他性 仅当前连接可见,连接关闭后自动删除 临时任务(如分布式锁)
自动删除 最后一个消费者断开连接后自动删除队列 临时通知场景
容量限制 可设置最大长度(消息数或字节数),避免内存溢出 流量控制
消息优先级 支持为消息设置优先级,队列优先投递高优先级消息 紧急任务处理

# 1.6 消费者(Consumer)

角色定位:消息的处理者,监听队列并获取消息进行业务处理。 类比场景:取快递的用户,收到通知后处理包裹。 核心特性:

  • 需明确监听的队列;
  • 处理完成后需发送"确认信号"(Ack),RabbitMQ才会删除消息(避免消息丢失);
  • 可多个消费者共同监听一个队列,实现负载均衡。

代码示例(消息消费):

@Service
public class OrderConsumer {
    @RabbitListener(queues = "order.queue") // 监听指定队列
    public void handleOrder(Order order, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        try {
            // 处理业务逻辑(如更新订单状态)
            processOrder(order);
            // 手动确认消息(消息处理成功,RabbitMQ删除消息)
            channel.basicAck(tag, false);
        } catch (Exception e) {
            // 处理失败,消息重回队列(或进入死信队列)
            channel.basicNack(tag, false, true);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 1.7 消息流转完整流程

  1. 生产者创建消息,指定交换机名称和路由键,发送到RabbitMQ;
  2. 交换机根据自身类型和与队列的绑定规则,将消息转发到匹配的队列;
  3. 队列存储消息,等待消费者处理;
  4. 消费者监听队列,获取消息并处理;
  5. 消费者处理完成后发送Ack确认,队列删除消息。

# 二、交换机类型:不同场景的路由策略

交换机的类型决定了消息的转发逻辑,需根据业务场景选择:

# 2.1 Direct Exchange(直连交换机)

路由逻辑:仅当消息的路由键与队列和交换机的绑定键完全一致时,消息才会被转发。 适用场景:精确路由(如"订单创建"消息仅发给订单处理服务)。

示例流程:

  • 交换机direct.exchange与队列queue1绑定,绑定键为order.create;
  • 生产者发送路由键为order.create的消息 → 消息被转发到queue1;
  • 若路由键为order.pay → 无匹配队列,消息被丢弃。

# 2.2 Topic Exchange(主题交换机)

路由逻辑:支持通配符匹配路由键,灵活性最高。

  • *:匹配1个单词(如order.*可匹配order.create、order.pay,但不匹配order.pay.success);
  • #:匹配0个或多个单词(如order.#可匹配order、order.create、order.pay.success)。

适用场景:按"主题"分类的消息(如日志系统,log.error、log.warn可被不同队列接收)。

示例流程:

  • 交换机topic.exchange与队列errorQueue绑定,绑定键为log.error;
  • 与队列allLogQueue绑定,绑定键为log.#;
  • 发送路由键为log.error.db的消息 → 同时转发到errorQueue和allLogQueue。

# 2.3 Fanout Exchange(扇形交换机)

路由逻辑:完全忽略路由键和绑定键,所有绑定该交换机的队列都会收到消息(广播模式)。 适用场景:消息需要被多个消费者处理(如订单创建后,通知库存、支付、物流服务)。

示例流程:

  • 交换机fanout.exchange绑定了stockQueue、payQueue、logisticsQueue;
  • 生产者发送消息(无需指定路由键) → 三个队列均收到消息。

# 2.4 Headers Exchange(头交换机)

路由逻辑:不依赖路由键,通过消息的头信息(Headers) 匹配绑定规则。

  • 绑定队列时需指定一组键值对(如{"type":"order", "priority":"high"});
  • 匹配模式:x-match=all(需所有头信息匹配)或x-match=any(任意一个匹配)。

适用场景:路由规则复杂(需多条件匹配)的场景(较少使用,通常可用Topic替代)。

# 三、高级特性:确保消息可靠与高效

# 3.1 负载均衡:prefetch配置

问题:若队列有100条消息,2个消费者监听时,默认会平均分配(各50条)。若其中一个消费者处理慢,会导致消息堆积。

解决方案:通过prefetch控制消费者预取消息数量:

  • prefetch=1:消费者必须处理完当前消息并确认后,才能获取下一条(轮询分配,负载均衡)。

配置示例(application.yml):

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只预取1条消息
        acknowledge-mode: manual # 手动确认(配合prefetch生效)
1
2
3
4
5
6

# 3.2 消息持久化

为避免RabbitMQ重启后消息丢失,需同时配置:

  1. 交换机持久化:声明交换机时设置durable=true;
  2. 队列持久化:声明队列时设置durable=true;
  3. 消息持久化:发送消息时设置deliveryMode=2(Spring AMQP默认持久化)。

# 3.3 消息确认机制

  • 生产者确认:确保消息成功发送到交换机(通过publisher-confirm-type配置);
  • 消费者确认:确保消息被正确处理(手动Ack,避免处理失败后消息丢失)。

# 总结

RabbitMQ的核心价值在于通过"组件解耦"和"异步通信"提升分布式系统的可靠性与效率。

编辑 (opens new window)
#RabbitMQ#MQ队列
上次更新: 2026/01/21, 19:29:14
RabbitMQ集群

RabbitMQ集群→

最近更新
01
订单超时取消
01-21
02
双 Token 登录
01-21
03
长短链接跳转
01-21
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式