RabbitMQ 快速入门
RabbitMQ 是一款实现了 AMQP 协议的消息中间件,使用 Erlang 编写。这篇博客简单介绍一下 RabbitMQ, 但不介绍特定库的 API
核心概念
RabbitMQ 存在一下概念,清楚了一下概念也就基本了解了 RabbitMQ
- 发布者
- 消费者
- 帧
- 消息
- 连接
- 信道 Channel
- 交换机
- 队列
- 死信队列
- 路由键
- properties
- 绑定
首先 发布者将消息发布到 RabbitMQ, 消费者从 RabbitMQ 中拉取消息(获取被推送消息)。对于开发来说,发布者是将带有指定路由键的消息发送到 RabbitMQ 的指定交换机,加入此时没有合适的路由,消息将被遗失。
消费者通过队列获取消息,所以如果对应的消费者想要拿到消息,交换机应该将对应的消息路由到对应的队列,而控制交换机是否应该将某条消息路由到指定的队列的规则成为绑定,一条绑定至少需要以下三条信息:
- 交换机名称
- 队列名称
- 路由键
一条消息必须负责以上三个条件才能被路由。
帧是发送消息的实际载体,分为以下三类:
- 方法帧
- 内容头帧
- 消息体帧
方法帧有实际的 AMQP RPC 指令,内容头帧保存消息的一些额外信息,例如消息后,属性等。消息体帧保存实际的消息内容,帧的大小存在限制,如果消息内容超过了限制,那么消息内容将会被分为多个消息体帧。
对于客户端库来说,可以创建一个到 RabbitMQ Server 的 TCP 连接,在这个连接上可以创建多个 Channel,不同的 Channel 之前不会相互干扰,是隔离的。同时需要记住发布消息的频道和消费消息的频道应该
分开。
RabbitMQ 必须保证消息的可靠性,举例来说,如果发布者发布成功了一条消息到 Rabbit,那么他应该收到一条 ack 响应,否则不应该认为消息发布成功。同样的,如果消费者获取或者接受到了一条消息,同样必须向
RabbitMQ 发送一条 ack 请求,告诉 Rabbit 消息已经接受到,否则在此之前消息的状态都将会是 unack 的,不会被删除,如果在对应的信道断开以后,这条消息还是 unack 的,那么消息将会回到队列之中。
一条消息除了携带指定的消息内容以外,还可以携带额外的数据,这部分额外的附加数据成为 Properties,有些 property 将会影响 RabbitMQ 对消息的操作行为,有些 property 可以作为应用的消息的额外数据。
与 ack 对应的是 nack 或者说 reject,一个队列启用了死信交换机,那么当消息被拒接或者过期的时候,消息将会被发送到死信交换机,死信交换机和别的普通交换机来说没有什么区别,你可以声明一个普通的交换机,
然后在声明一个队列的时候指定其为该队列的死信交换机,然后该队列的所有死信都将发送到该交换机,如果你想要消费 “死信”,那么应该在该交换机上面绑定队列。
根据交换机如何路由消息来分,内置交换机交换机可以分为四个类型,同时这里介绍一个作为 Rabbit 扩展的(自带的)交换机类型:
- direct
- fanout
- topic
- headers
- consistent hash
direct 类型的交换机,也是最常用的交换,只将 routing key 匹配的消息路由到指定的队列。
fanout 类型的交换机将消息发送到所有绑定的队列。
topic 交换机和 direct 类型,不同 routing key 允许使用通配符,routing key 的格式类似于命名空间 a.b.c,topic 交换机将消息发送到 routing key 能够匹配上的队列
consistent hash 交换机根据指定的 routing key hash 或者指定 hader 的 hash 配置到设置了指定权重的队列