RabbitMQ和通道和连接的关系

RabbitMQ Java客户端具有以下概念:

  • Connection – 连接到RabbitMQ服务器实例
  • Channel – ???
  • 消费者线程池 – 消耗RabbitMQ服务器队列中的消息的线程池
  • 队列 – 按FIFO顺序保存消息的结构

我试图理解这种关系, 更重要的是他们之间的关系。

  1. 我还不太确定一个Channel是什么,除了这是你发布和消费的结构,而且是从一个开放的连接创build的。 如果有人能向我解释“频道”代表什么,这可能有助于澄清一些事情。
  2. 频道和队列之间的关系是什么? 是否可以使用同一个通道与多个队列通信,还是必须是1:1?
  3. 队列和消费者池之间的关系是什么? 多个消费者可以订阅相同的队列吗? 多个队列可以被同一个消费者使用吗? 或者是1:1的关系?

在此先感谢您的帮助!

  1. 一个Connection表示一个到消息代理的真正的TCP连接,而一个Channel是一个虚连接(AMPQ连接)。 这样,您可以在应用程序内部使用尽可能多的(虚拟)连接,而无需使用TCP连接重载代理。

  2. 你可以使用一个Channel的一切。 但是,如果您有多个线程,build议为每个线程使用不同的Channel

    Java客户端API指南中的通道线程安全 :

    通道实例对于multithreading使用是安全的。 对一个通道的请求是序列化的,一次只有一个线程能够在通道上运行一个命令。 即使如此,应用程序应该更喜欢使用每个线程的通道,而不是在多个线程之间共享相同的通道。

    ChannelQueue之间没有直接的关系。 Channel用于向代理发送AMQP命令。 这可以是创build一个队列或类似的,但这些概念不绑定在一起。

  3. 每个Consumer运行在从消费者线程池分配的自己的线程中。 如果多个消费者订阅相同的队列,那么代理使用循环法来平均地在他们之间分配消息。 参见教程二:“工作队列” 。

    也可以将相同的Consumer附加到多个队列。 你可以把消费者理解为callback。 每次消息到达队列时,都会调用这些消息。 对于Java客户端的情况,每个消费者都有一个方法handleDelivery(...) ,它代表了callback方法。 你通常做的是,子类DefaultConsumer和重写handleDelivery(...) 。 注意:如果将相同的Consumer实例附加到多个队列,则此方法将由不同的线程调用。 所以如果需要的话,照顾同步。

我发现这篇文章解释了AMQP模型的所有方面,其中,渠道是一个。 我觉得这对我的理解非常有帮助

https://www.rabbitmq.com/tutorials/amqp-concepts.html

某些应用程序需要多个连接到AMQP代理。 但是,同时打开许多TCP连接是不可取的,因为这样做会占用系统资源,使得configuration防火墙变得更加困难。 AMQP 0-9-1连接与可被认为是“共享单个TCP连接的轻量级连接”的通道复用。

对于使用多个线程/进程进行处理的应用程序来说,每个线程/进程打开一个新通道并且不共享它们之间的通道是非常常见的。

特定信道上的通信与另一个信道上的通信完全分离,因此每个AMQP方法还携带一个客户端用来确定该方法用于哪个信道的通道号(例如,需要调用哪个事件处理程序) 。