无论是生产 者还是消费者,都需要和 RabbitMQ Broker 建立连接,这个连接就是一条 TCP 连接,也就是 Connection。 一旦 TCP 连接建立起来,客户端紧接着可以创建一个 AMQP 信道 (Channel) ,每 个信道都会被指派一个唯一 的 D 。信道是建立在 Connection 之上的虚拟连接, RabbitMQ 处理 的每条 AMQP 指令都是通过信道完成的。

rabbitmq中的Connection 和 Channel_数据

为什么还要引入信道呢? 

试想这样一个场景,一个应用程序中有很多个线程需要从 RabbitMQ 中消费消息,或者生产消息,那 么必然需要建立很多个 Connection ,也就是许多个 TCP 连接。然而对于操作系统而言,建立和 销毁 TCP 连接是非常昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现。 RabbitMQ 采用 类似 NIO' (Non-blocking 1/0) 的做法,选择 TCP 连接复用,不仅可以减少性能开销,同时也 便于管理 。

1 NIO ,也称非阻塞 UO , 包含三大核心部分Channel (信道)、 Buffer (缓冲区)和 Selector (选择器). NIO 基于 Channel 和Buffer 进行操作,数据总是从信道读取数据到缓冲区中,或者从缓冲区写入到信道中。 Selector 用于监听多个信道的事件(比 如连接打开,数据到达等)。因此,单线程可以监听多个数据的信道。 NIO 中有一个很有名的 Reactor 模式,有兴趣的读者可以深入研究。

每个线程把持一个信道,所以信道复用了 Connection 的 TCP 连接。同时 RabbitMQ 可以确 保每个线程的私密性,就像拥有独立的连接一样。当每个信道的流量不是很大时,复用单一 的 Connection 可以在产生性能瓶颈的情况下有效地节省 TCP 连接资源。但是当信道本身的流量很 大时,这时候多个信道复用一个 Connection 就会产生性能瓶颈,进而使整体的流量被限制了。 此时就需要开辟多个 Connection,将这些信道均摊到这些 Connection 中

注意要点:

Channel 可以用来发送或者接收消息了。Connection 可以 用来创建多个 Channel 实例,但是 Channel 实例不能在线程问共享, 应用程序应该为每一个线程开辟一个 Channel 。某些情况下 Channel 的操作可以并发运行,但 是在其他情况下会导致在网络上出现错误的通信帧交错,同时也会影响友送方确认( publisher confrrm)机制的运行(详细可以参考 4.8 节),所以多线程问共享 Channel 实例是非线程安全的 。