RabbitMQ从入门到精通---基础概念

上面我们说了RabbitMQ及其插件安装过程,算是动手入门了,这次我们来说说RabbitMQ基础概念,夯实理论基础。

RabbitMQ结构

首先我们来看看RabbitMQ的结构

RabbitMQ Server

也叫Broker,它就是维护一条从Producer到Consumer的路线,保证数据能够按照指定的方式进行传输。

生产者(Producer)

图中ClientA & B就是生产者,它们负责生产Message(消息),每一条Message由有效载荷(Payload)和标签(label组成),payload顾名思义就是传输的数据。label是exchange的名字或者说是一个tag,它描述了payload,而且RabbitMQ也是通过这个label来决定把这个Message发给哪个Consumer。

消费者(Consumer)

图中Client1 & 2 & 3均是消费者,他们接收Message,此时Message只有payload,label已经被删除。

交换机(Exchange)

接收生产者发来的消息,并根据规则进行路由。有三种常用类型的Exchanges:direct, fanout, topic,还有一种不常用的headers类型。 每个实现了不同的路由算法(routing algorithm)。生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个或多个Queue中(或者丢弃,当Queue不存在)。

  • Direct Exchange: 如果 routing key 匹配, 那么Message就会被传递到相应的Queue中。其实在queue创建时,它会自动的以queue的名字作为routing key来绑定那个Exchange。

  • Fanout Exchange: 会向响应的queue广播。

  • Topic Exchange: 对key进行模式匹配,比如ab*可以传递到所有ab*的Queue,匹配一个单词,#匹配0或多个单词,所以声明bingdingKey的时候,请使用“.”进行分割。当routingKey为“#”时,TopicExchange变为FanoutExchange,当routingKey不包含“\”或“#”时,它就变成了DirectExchange。

  • Headers Exchange: headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。

队列(Queue)

消息消费前存放的地方,

路由键(Routing key)和绑定键(Binding key)

其实二者是指一个东西,只是逻辑上不太一样。

队列(Queue)通过BindingKey和交换机(Exchange),而消息(Message)发送的时候需要指定RoutingKey,交换机将会对绑定键(binding key)和路由键(routing key)进行精确匹配,从而确定消息该分发到哪个队列。

生产者发送消息的时候,需要指定exchange和routingKey,才能找到对用的exchange,然后通过routingKey找到相应的队列。如果不指定exchange,消息会发往rabbitMQ默认的名称为“”的exchange,这个exchange默认被绑定到任何队列上,此时如果不指定routingKey或routingKey不等于任何队列的名字,该消息会被丢弃,否则被发往名称和routingKey相同的队列。

Virtual hosts

虚拟主机,每个virtual host本质上都是一个RabbitMQ Server,拥有它自己的queue,exchagne,和bings rule等等。这保证了你可以在多个不同的application中使用RabbitMQ。

参考链接

摘自anzhsoft博客的三个问题,留作思考。

  1. Will “*“ binding catch a message sent with an empty routing key?
  2. Will “#.*“ catch a message with a string “..” as a key? Will it catch a message with a single word key?
  3. How different is “a.*.#” from “a.#”?
我知道是不会有人点的,但万一有人想不开呢!