核心概念#
RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。
RabbitMQ 整体架构
- Producer(生产者)和 Comsumer(消费者)
- 消息组成:
- 消息头(Label):
- routing-key(路由键)
- priority(相对于其他消息的优先权)
- delivery-mode(持久性存储)
- 消息体(payload)
- 消息头(Label):
- Exchange(交换器):生产者将消息发给 Exchange,其再将消息路由到一个或多个队列中,如果路由不到,则返回给生产者或直接丢弃
-
流程:Publish Message + RoutingKey → Exchange → Binding Key → Queue > Comsume
-
常用类型:
-
direct(默认):将消息路由到 BindingKey 与 RoutingKey 完全匹配的 Queue 中。常用在处理有优先级的任务
-
fanout:将消息路由到所有与它绑定的 Queue 中。常用来广播消息
-
topic:将消息路由到 **BindingKey 和 RoutingKey 相匹配(完全匹配或模糊匹配)** 的队列中
- BindingKey 和 RoutingKey 是用点号 “.” 分隔的字符串
- BindingKey 中可以存在两种模糊匹配字符串 “*”(匹配一个单词) 和 “#”(匹配 0 个或多个单词)
-
headers(不推荐):依赖消息内容中的 headers 属性进行匹配,性能差,不实用,基本不用
-
-
- Queue(消息队列):消息的容器,一个消息可投入一个或多个队列。
- 消费:支持单个或多个消费者(平均分摊 Round-Robin)订阅同一队列
- Binding(绑定):通过 BindingKey 将 Queue 绑定到 Exchange
- Broker(消息中间件的服务节点):一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点或者 RabbitMQ 服务实例
- Dead Letter Exchange(死信交换器):当消息在队列中变成死信(dead message)后,就被发送到死信交换器
- 死信原因:
- 消息被拒(Basic.Reject/ Basic.Nack)且 requeue = false
- 消息 TTL 过期
- 队列满了
- 死信原因:
- 延迟队列:消息在特定时间后才被消费
- 实现方式:
- 使用 RabbitMQ 的死信交换器(Dead Letter Exchange)和消息的存活时间(TTL)
- 使用 RabbitMQ 3.5.7+ 开发的插件(rabbitmq-delayed-message-exchange)
- 实现方式:
- 优先级队列:RabbitMQ 3.5.0+ 通过
x-max-priority
参数实现。当消费速度大于生产速度且 Broker 没有堆积的情况下,该参数没有意义 - 消息传输:基于建立在 TCP 连接上的信道(Channel),数量无限制,每个信道在 RabbitMQ 都有唯一的 ID,对应一个线程使用
- 消息可靠性:
- 生产者到 RabbitMQ:事务机制或 Confirm 机制,注意:事务机制和 Confirm 机制是互斥的,两者不能共存,会导致 RabbitMQ 报错
- RabbitMQ 自身:持久化、普通集群、镜像集群
- RabbitMQ 到消费者:basicAck 机制、死信队列、消息补偿机制
- 消息顺序性:
- 拆分为多个 queue,每个 queue 一个 consumer(会造成吞吐量下降)
- consumer 不消费消息,而是根据消息中的关键值进行哈希(比如 ID,即相同 ID 下的多条消息),再根据哈希值进行分组到不同的内存 queue 中,最后每组交给不同的 worker 也就是子线程去处理(在消费者内部采用多线程的方式消费)
- 高可用:
- 普通集群:数据都在主节点,从节点只同步主节点中 queue 的 metadata,不同步消息
- 镜像集群:主从节点数据完全同步