rabbitmq相关概念
生产者
- 生产者即为投递消息的一方
- 消息分为两部分:消息体(payload)和标签 (label)
- 消息体一般是带有业务逻辑的结构数据,比如json字符串
- 消息的标签用来表述这条消息,比如一个交换器的名称和路由键
消费者
- 消费者即为接受消息的一方
###Broker
- 对于 RabbitMQ 来说, 一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点, 或者 RabbitMQ 服务实例。 大多数情况下也可以将一个 RabbitMQ Broker 看作一 台 RabbitMQ 服务器
- 生产者将消息存入 RabbitMQ Broker, 以及消费者从 Broker 中消费数据的整 个流程

队列
- Queue:队列,是 RabbitMQ 的内部对象,用于存储消息 。
- RabbitMQ 中消息都只能存储在队列中,这一点和 Kafka 这种消息中间件相反。 Kafka 将消 息存储在 topic (主题)这个逻辑层面,而相对应的队列逻辑只是 topic 实际存储文件中的位移 标识。 RabbitMQ 的生产者生产消息井最终技递到队列中,消费者可以从队列中获取消息并消费 。
- RabbitMQ 不支持队列层面的广播消费,如果需要广播消费,需要在其上进行二次开发,处理逻辑会变得异常复杂,同时也不建议这么做。
交换器
- Exchange:交换器
- 生产者将消息发送到 Exchange (交换器,通常也 可以用大写的“X”来表示),由交换器将消息路由到一个或者多个队列中。如果路由不到,或 许会返回给生产者,或许直接丢弃。
路由键
- RoutingKey:路由键。
- 生产者将消息发给交换器的时候, 一般会指定一个 RoutingKey,用 来指定这个消息的路由规则,而这个 Routing Key 需要与交换器类型和绑定键( BindingKey )联 合使用才能最终生效。
- 在交换器类型和绑定键( BindingKey )固定的情况下,生产者可以在发送消息给交换器时, 通过指定 RoutingKey 来决定消息流向哪里。
绑定
- Binding:绑定 。
- RabbitMQ 中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一个绑定键( BindingKey ),这样 RabbitMQ 就知道如何正确地将消息路由 到 队列了,
rabbitmq整体流程架构图

RoutingKey和BindingKey
- BindingKey 并不是在所有的情况下都生效 ,它依赖于交换器类型, 比 如 fanout 类型的交换器就会无视 BindingKey, 而是将消息路由 到所有绑定到该交换器的队列中
- 在 direct 交换器类型下, RoutingKey 和 BindingKey 需要完全匹配才能使用
- 在 topic 交换器类型下,RoutingKey 和 BindingKey 之间需要做模糊匹配, 两者并不是相同的。
- BindingKey 其实也属于路由键中的一种, 官方解释为 : the routing key to use for the binding。 可以翻译为:在绑定的时候使用的路由键。 大多数时候, 包括官方文档和 RabbitMQ Java API中都把 BindingKey 和 RoutingKey 看作 RoutingKey, 为了避免混淆,可以这么理解:
- 在使用绑定的时候, 其中需要的路由键是 BindingKey 。涉及的客户端方法如: channel.exchangeBind、 channel .queueBind, 对应的 AMQP 命令为 Exchange.Bind、 Queue.Bind。
- 在发送消息的时候, 其中需要的路由键是RoutingKey 。涉及的客户端方法如channel.basicPublish ,对应的 AMQP 命令为 Basic.Publish。
交换器类型
- RabbitMQ 常用的交换器类型有 fanout、 direct、 topic、 headers 这四种 。 AMQP 协议里还提 到另外两种类型: System 和自定义。
- fanout
- 它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。
- direct 类型的交换器路 由规则也很简单 完全匹配的队列 中。
- topic 类型的交换器在 匹配规则上进行 了扩展, 它与 direct 类型的交换器相 似, 也是将消息路由到 BindingKey 和 RoutingKey相匹配的队列中, 但这里的匹配规 则有些不同, 它约定 :
- RoutingKey为一个"."号分隔的字符串(被点号"."分隔开的每一段独立的字符串成为一个单词),如"com.rabbitmq.client"
- BindingKey 和 RoutingKey一样也是点号“ .”分隔的字符串;
- BindingKey 中可以存在两种特殊字符串“* ”和“#”, 用于做模糊匹配, 其中“* ”用于匹配一个单词, “#”用于匹配多规格单词(可以是零个)。
- headers 类型的交换器不依赖于路由键 的匹配规则来路由消息, 而是根据发送的消息内容中 的 headers 属性进行匹配。 在绑定队列和交换器时制定一组 键值对, 当发送消息到交换器时, RabbitMQ 会获取到该消息的 headers (也是一个键值对的形式〉 ,对比其中的键值对是否完全 匹配队列和交换器绑定时指定 的键值对, 如果完全匹配则消息会路由到 该队列, 否则不会路由 到该队列 。 headers 类型的交换器性能会很差, 而且也不实用, 基本上不会看到它的存在。
RabbitMQ 运转流程
- 生产者连接到RabbitMQ Broker,建立一个链接(connection),开启一个信道(channel)
- 生产者声明一个交换器,并设置相关属性,比如交换器类型、是否持久化等
- 生产者声明一个队列,并设置相关属性,比如是否排他、是否持久化、是否自动删除等
- 生产者通过路由键将交换器和路由键绑定起来
- 生产者发送消息至RabbitMQ Broker, 其中包含路由键 、交换器等信息
- 相应的交换器根据接收到的路由键查找相匹配的队列
- 如果找到, 则将从生产者发 送过来的消息存 入相应的队列中 。
- 如果没有找到 , 则根据生产者配置的属性选择丢弃还是回退给生产者
- 关闭信道
- 关闭连接
- 消费者连接到 RabbitMQ Broker, 建立一个连接( Connection ), 开启一个信道( Channel)
- 消费者向 RabbitMQ Broker 请求消费相应队 列中的消息, 可能会设置相应 的回调函数, 以及做一些准备 工作
- 等待 RabbitMQ Broker 回应并投递相应 队列中的消息, 消费者接收消息
- 消费者确认( ack )接收到的消息
- RabbitMQ 从队列中删除相应己经被确认的消息
- 关闭信道
- 关闭连接