RabbitMQ通信过程分析

RabbitMQ通信过程分析

总体流程概述:

生产者创建消息,并将消息投递给RabbitMq,具体来说,应该是RabbitMQ的交换器(Exchange),然后交换器根据规则(routing key),决定将消息投递到对应的队列(queues),这时候,监听队列的消费者就可以获取到消息了。

关键词:交换器、队列、绑定、路由键

具体流程如下:

  1. 生产者建立到RabbitMQ的TCP连接。在TCP的基础上,创建信道。信道是在建立在“真实的”TCP连接内的虚拟连接。不论是发布消息、订阅队列或是接收消息,这些动作都是通过信道完成的。可以把TCP想象成为一束光纤电缆,而信道是电缆中每条光纤。
  2. 生产者发送消息。消息包括两部分内容:有效荷载和标签。有效荷载是生产者要发送的数据,而标签对有效荷载的描述,它决定了谁将获得这些消息,具体内容包括交换器名称、路由键名称、编码、content-type、数据类型(如字符串还是自定义的类型)、delivery_mode等等。可以在管理界面—queues—get message中查看。
  3. 消息路由。路由器实际上只是一张查询表,表中记录了路由模式列表和匹配消息应发往的队列进程ID列表。当发布的消息匹配了交换器中的绑定规则时,实际上是由信道完成了匹配工作,并在匹配后建立到队列PID的连接,然后将消息传送过去。
  4. 队列对消息的处理。如果至少有一个消费者订阅了队列的话,消息会立即发送给订阅的消费者。如果消息到了无人订阅的队列,消息会在队列中等待,一旦有消费者订阅到该队列,队列上的消息就会发送给订阅者;当队列有多个消费者时,队列将消息以循环(round-robin)的方式发送给消费者;
  5. 消费者接收消息。消费者通过两种方式从队列中接收消息:同步(basic.get)和异步(basic.consume)。basic.get只能接收单条消息,如果想要获得更多的消息,需要再次发送basic.get命令,或者放在一个循环里,但是这样的性能不好,建议使用basic.consume。basic.consume模式,会在消息到达队列后,消费者自动接收消息,提高吞吐量。
  6. 消费者对消息的确认。消费者可以选择在接收到消息后对消息进行确认,这样是为了保证可靠性,但会带来性能上的损耗。可以设置auto_ack为true,一旦消费者接收到消息后,RabbitMQ就自动确认该消息;也可以手动进行确认。如果应用程序崩溃了导致没有确认消息,Rabbit会将消息发送给其他消费者;另一方面,如果没有确认消息的话,Rabbit将不会给该消费者发送更多的消息了,这是因为在上一条消息确认前,Rabbit认为这个消费者还没有准备好接收下一条消息。如果消费者想拒绝消息的话,可以使用reject命令。如果reject命令的requeue参数为true,RabbitMQ会将消息发送给下一个订阅的消费者;如果设为false的话,会将消息从队列中移除。

消息投递流程补充

rabbitmq消息投递流程