【RabbitMQ实战】消息通信概念——消费者、生产者和代理

生产者(producer)创建消息,然后发布(发送)到代理服务器(RabbitMQ)。

消息包含两部分内容:有效载荷(payload)和标签(label)。有效载荷就是想要传输的数据。它可以是任何内容。标签描述了有效载荷,并且RabbitMQ用它来决定谁将获得消息的拷贝。举例来说,不同于TCP协议的是,当明确指定发送方和接收方时,AMQP只会用标签表述这条消息(一个交换器的名称和可选的主题标记),然后把消息交由Rabbit。Rabbit会根据标签把消息发送给感兴趣的接收方。这种通信方式是一种“发后即忘”(fire-and-forget)的单向方式。

333Oyt.png

消费者连接到代理服务器上,并订阅到队列(queue)上。每当消息到达特定的消息队列时,RabbitMQ会将其发送给其中一个订阅的/监听的消费者。当消费者接收到消息时,它只得到消息的一部分:有效载荷。在消息路由过程中,消息的标签并没有随有效载荷一同传递。RabbitMQ甚至不会告诉是谁生产/发送了消息。如果需要明确知道是谁生产的AMQP消息的话,就要看生产者是否把发送方信息放入有效载荷中。

整个过程其实很简单:生产者创建消息,消费者接收这些消息。应用程序可以作为生产者,向其他应用程序发送消息。或者作为一个消费者,接收消息。也可以在两者之间进行切换。不过在此之前,它必须先建立一条信道(channel)。

必须首先连接到Rabbit,才能消费或者发布消息。在应用程序和Rabbit代理服务器之间创建一条TCP连接。一旦TCP连接打开(通过了认证),应用程序就可以创建一条AMQP信道。信道是建立在“真实的”TCP连接内的虚拟连接。AMQP命令都是通过信道发送出去的。每条信道都会被指派一个唯一ID(AMQP库会记住ID的)。不论是发布消息、订阅队列或是接收消息,这些动作都是通过信道完成的。

为什么需要信道呢?为什么不直接通过TCP连接发送AMQP命令呢?主要原因在于对操作系统来说建立和销毁TCP会话是非常昂贵的开销。假设应用程序从队列消费消息,并根据服务需求合理调度线程。假设只进行TCP连接,那么每个线程都需要自行连接到Rabbit。也就是说高峰期有每秒成百上千条连接。这不仅造成TCP连接的巨大浪费,而且操作系统每秒也就只能建立这点数量的连接。因此,可能很快就碰到性能瓶颈了。如果为所有线程只使用一条TCP连接以满足性能方面的要求,但又能确保每个线程的私密性,就像拥有独立连接一样的话,那不就非常完美吗?这就是要引入信道概念的原因。线程启动后,会在现成的连接上创建一条信道,也就获得了连接到Rabbit上的私密通信路径,而不会给操作系统的TCP栈造成额外负担。

3Gb9Z4.png