Java RabbitMQ 和通道与连接的关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18418936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RabbitMQ and relationship between channel and connection
提问by
The RabbitMQ Java clienthas the following concepts:
该RabbitMQ的Java客户端具有以下概念:
Connection
- a connection to a RabbitMQ server instanceChannel
- ???- Consumer thread pool - a pool of threads that consume messages off the RabbitMQ server queues
- Queue - a structure that holds messages in FIFO order
Connection
- 到 RabbitMQ 服务器实例的连接Channel
- ???- 消费者线程池 - 使用 RabbitMQ 服务器队列中的消息的线程池
- 队列 - 按 FIFO 顺序保存消息的结构
I'm trying to understand the relationship, and more importantly, the associationsbetween them.
我试图了解这种关系,更重要的是,了解它们之间的关联。
- I'm still not quite sure what a
Channel
is, other than the fact that this is the structure that you publish and consume from, and that it is created from an open connection. If someone could explain to me what the "Channel" represents, it might help clear a few things up. - What is the relationship between Channel and Queue? Can the same Channel be used to communicate to multiples Queues, or does it have to be 1:1?
- What is the relationship between Queue and the Consumer Pool? Can multiple Consumers be subscribed to the same Queue? Can multiple Queues be consumed by the same Consumer? Or is the relationship 1:1?
- 我仍然不太确定 a
Channel
是什么,除了事实上这是您发布和使用的结构,并且它是从开放连接创建的。如果有人可以向我解释“频道”代表什么,它可能有助于澄清一些事情。 - 通道和队列是什么关系?可以使用同一个 Channel 与多个 Queues 通信,还是必须是 1:1?
- Queue和Consumer Pool是什么关系?多个消费者可以订阅同一个队列吗?同一个消费者可以消费多个队列吗?还是1:1的关系?
Thanks in advance for any help here!
在此先感谢您的帮助!
采纳答案by Bengt
A
Connection
represents a real TCP connection to the message broker, whereas aChannel
is a virtual connection (AMQP connection) inside it. This way you can use as many (virtual) connections as you want inside your application without overloading the broker with TCP connections.You can use one
Channel
for everything. However, if you have multiple threads, it's suggested to use a differentChannel
for each thread.Channel thread-safety in Java Client API Guide:
Channel instances are safe for use by multiple threads. Requests into a Channel are serialized, with only one thread being able to run a command on the Channel at a time. Even so, applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads.
There is no direct relation between
Channel
andQueue
. AChannel
is used to send AMQP commands to the broker. This can be the creation of a queue or similar, but these concepts are not tied together.Each
Consumer
runs in its own thread allocated from the consumer thread pool. If multiple Consumers are subscribed to the same Queue, the broker uses round-robin to distribute the messages between them equally. See Tutorial two: "Work Queues".It is also possible to attach the same
Consumer
to multiple Queues. You can understand Consumers as callbacks. These are called everytime a message arrives on a Queue the Consumer is bound to. For the case of the Java Client, each Consumers has a methodhandleDelivery(...)
, which represents the callback method. What you typically do is, subclassDefaultConsumer
and overridehandleDelivery(...)
. Note: If you attach the same Consumer instance to multiple queues, this method will be called by different threads. So take care of synchronization if necessary.
A
Connection
表示到消息代理的真实 TCP 连接,而 aChannel
是其中的虚拟连接(AMQP 连接)。通过这种方式,您可以在应用程序中使用任意数量的(虚拟)连接,而不会使用 TCP 连接使代理过载。你可以
Channel
为所有事情使用一个。但是,如果您有多个线程,建议Channel
为每个线程使用不同的线程。通道实例可供多个线程安全使用。对 Channel 的请求是序列化的,一次只有一个线程能够在 Channel 上运行命令。即便如此,应用程序应该更喜欢每个线程使用一个通道,而不是跨多个线程共享同一个通道。
Channel
和之间没有直接关系Queue
。AChannel
用于向代理发送 AMQP 命令。这可以是创建队列或类似的,但这些概念并不联系在一起。每个都
Consumer
在从使用者线程池分配的自己的线程中运行。如果多个 Consumer 订阅了同一个 Queue,则代理使用轮询机制在它们之间平均分配消息。请参阅教程二:“工作队列”。也可以将相同的附加
Consumer
到多个队列。您可以将消费者理解为回调。每次消息到达消费者绑定的队列时都会调用它们。对于 Java Client 的情况,每个 Consumers 都有一个 methodhandleDelivery(...)
,代表回调方法。你通常做的是, subclassDefaultConsumer
和 overridehandleDelivery(...)
。注意:如果将同一个 Consumer 实例附加到多个队列,这个方法会被不同的线程调用。因此,如有必要,请注意同步。
回答by CamW
I found this article which explains all aspects of the AMQP model, of which, channel is one. I found it very helpful in rounding out my understanding
我发现这篇文章解释了 AMQP 模型的所有方面,其中,通道就是其中之一。我发现它对完善我的理解很有帮助
https://www.rabbitmq.com/tutorials/amqp-concepts.html
https://www.rabbitmq.com/tutorials/amqp-concepts.html
Some applications need multiple connections to an AMQP broker. However, it is undesirable to keep many TCP connections open at the same time because doing so consumes system resources and makes it more difficult to configure firewalls. AMQP 0-9-1 connections are multiplexed with channels that can be thought of as "lightweight connections that share a single TCP connection".
For applications that use multiple threads/processes for processing, it is very common to open a new channel per thread/process and not share channels between them.
Communication on a particular channel is completely separate from communication on another channel, therefore every AMQP method also carries a channel number that clients use to figure out which channel the method is for (and thus, which event handler needs to be invoked, for example).
某些应用程序需要多个连接到 AMQP 代理。但是,同时保持许多 TCP 连接打开是不可取的,因为这样做会消耗系统资源并且使配置防火墙更加困难。AMQP 0-9-1 连接与可以被认为是“共享单个 TCP 连接的轻量级连接”的通道复用。
对于使用多个线程/进程进行处理的应用程序,为每个线程/进程打开一个新通道而不在它们之间共享通道是很常见的。
特定通道上的通信与另一个通道上的通信完全分开,因此每个 AMQP 方法还携带一个通道编号,客户端使用该编号来确定该方法用于哪个通道(例如,因此需要调用哪个事件处理程序) .
回答by theMayer
A good conceptual understanding of what the AMQP protocol does "under the hood" is useful here. I would offer that the documentation and API that AMQP 0.9.1 chose to deploy makes this particularly confusing, so the question itself is one which many people have to wrestle with.
对 AMQP 协议在“幕后”所做的事情的良好概念性理解在这里很有用。我认为 AMQP 0.9.1 选择部署的文档和 API 使这特别令人困惑,因此问题本身是许多人必须努力解决的问题。
TL;DR
TL; 博士
A connectionis the physical negotiated TCP socket with the AMQP server. Properly-implemented clients will have one of these per application, thread-safe, sharable among threads.
一个连接与AMQP服务器的物理协商TCP套接字。正确实现的客户端将为每个应用程序提供其中之一,线程安全,线程间可共享。
A channelis a single application session on the connection. A thread will have one or more of these sessions. AMQP architecture 0.9.1 is that these are not to be shared among threads, and should be closed/destroyed when the thread that created it is finished with it. They are also closed by the server when various protocol violations occur.
甲信道是连接上的单个应用会话。一个线程将有一个或多个这些会话。AMQP 架构 0.9.1 是这些不能在线程之间共享,并且应该在创建它的线程完成时关闭/销毁。当发生各种违反协议时,它们也会被服务器关闭。
A consumeris a virtual construct that represents the presence of a "mailbox" on a particular channel. The use of a consumer tells the broker to push messages from a particular queue to that channel endpoint.
甲消费者是表示一个“信箱”的特定频道上的存在的虚拟构建体。消费者的使用告诉代理将消息从特定队列推送到该通道端点。
Connection Facts
连接事实
First, as others have correctly pointed out, a connectionis the object that represents the actual TCP connection to the server. Connections are specified at the protocol level in AMQP, and all communication with the broker happens over one or more connections.
首先,正如其他人正确指出的那样,连接是表示与服务器的实际 TCP 连接的对象。连接是在 AMQP 中的协议级别指定的,与代理的所有通信都发生在一个或多个连接上。
- Since it's an actual TCP connection, it has an IP Address and Port #.
- Protocol parameters are negotiated on a per-client basis as part of setting up the connection (a process known as the handshake.
- It is designed to be long-lived; there are few cases where connection closure is part of the protocol design.
- From an OSI perspective, it probably resides somewhere around Layer 6
- Heartbeats can be set up to monitor the connection status, as TCP does not contain anything in and of itself to do this.
- It is best to have a dedicated thread manage reads and writes to the underlying TCP socket. Most, if not all, RabbitMQ clients do this. In that regard, they are generally thread-safe.
- Relatively speaking, connections are "expensive" to create (due to the handshake), but practically speaking, this really doesn't matter. Most processes really will only need one connection object. But, you can maintain connections in a pool, if you find you need more throughput than a single thread/socket can provide (unlikely with current computing technology).
- 因为它是一个实际的 TCP 连接,所以它有一个 IP 地址和端口号。
- 协议参数是在每个客户端的基础上协商的,作为建立连接的一部分(一个称为握手的过程。
- 它的设计寿命很长;连接关闭是协议设计的一部分的情况很少。
- 从 OSI 的角度来看,它可能位于第 6 层附近
- 可以设置心跳来监视连接状态,因为 TCP 本身不包含任何内容来执行此操作。
- 最好有一个专门的线程来管理对底层 TCP 套接字的读写。大多数(如果不是全部)RabbitMQ 客户端都会这样做。在这方面,它们通常是线程安全的。
- 相对而言,创建连接是“昂贵的”(由于握手),但实际上,这真的无关紧要。大多数进程实际上只需要一个连接对象。但是,您可以在池中维护连接,如果您发现需要比单个线程/套接字可以提供的吞吐量更大的吞吐量(用当前的计算技术不太可能)。
Channel Facts
渠道事实
A Channelis the application session that is opened for each piece of your app to communicate with the RabbitMQ broker. It operates over a single connection, and represents a sessionwith the broker.
一个通道是打开的,每件您的应用程序与RabbitMQ的代理进行通信的应用程序会话。它通过单个连接运行,并代表与代理的会话。
- As it represents a logical part of application logic, each channel usually exists on its own thread.
- Typically, all channels opened by your app will share a single connection (they are lightweight sessions that operate on top of the connection). Connections are thread-safe, so this is OK.
- Most AMQP operations take place over channels.
- From an OSI Layer perspective, channels are probably around Layer 7.
- Channels are designed to be transient; part of the design of AMQP is that the channel is typically closed in response to an error (e.g. re-declaring a queue with different parameters before deleting the existing queue).
- Since they are transient, channels should not be pooled by your app.
- The server uses an integer to identify a channel. When the thread managing the connection receives a packet for a particular channel, it uses this number to tell the broker which channel/session the packet belongs to.
- Channels are not generally thread-safe as it would make no sense to share them among threads. If you have another thread that needs to use the broker, a new channel is needed.
- 由于它代表应用程序逻辑的逻辑部分,因此每个通道通常存在于自己的线程中。
- 通常,您的应用程序打开的所有通道都将共享一个连接(它们是在连接之上运行的轻量级会话)。连接是线程安全的,所以没问题。
- 大多数 AMQP 操作发生在通道上。
- 从 OSI 层的角度来看,通道可能在第 7 层附近。
- 通道被设计为瞬态的;AMQP 设计的一部分是通道通常在响应错误时关闭(例如,在删除现有队列之前重新声明具有不同参数的队列)。
- 由于它们是暂时的,因此您的应用不应将通道合并。
- 服务器使用整数来标识通道。当管理连接的线程接收到特定通道的数据包时,它使用此编号告诉代理该数据包属于哪个通道/会话。
- 通道通常不是线程安全的,因为在线程之间共享它们是没有意义的。如果您有另一个线程需要使用代理,则需要一个新通道。
Consumer Facts
消费者事实
A consumer is an object defined by the AMQP protocol. It is neither a channel nor a connection, instead being something that your particular application uses as a "mailbox" of sorts to drop messages.
消费者是由 AMQP 协议定义的对象。它既不是通道也不是连接,而是您的特定应用程序用作某种“邮箱”来丢弃消息的东西。
- "Creating a consumer" means that you tell the broker (using a channelvia a connection) that you would like messages pushed to you over that channel. In response, the broker will register that you have a consumeron the channel and begin pushing messages to you.
- Each message pushed over the connection will reference both a channel numberand a consumer number. In that way, the connection-managing thread (in this case, within the Java API) knows what to do with the message; then, the channel-handling thread also knows what to do with the message.
- Consumer implementation has the widest amount of variation, because it's literally application-specific. In my implementation, I chose to spin off a task each time a message arrived via the consumer; thus, I had a thread managing the connection, a thread managing the channel (and by extension, the consumer), and one or more task threads for each message delivered via the consumer.
- Closing a connectioncloses all channels on the connection. Closing a channelcloses all consumers on the channel. It is also possible to cancela consumer (without closing the channel). There are various cases when it makes sense to do any of the three things.
- Typically, the implementation of a consumer in an AMQP client will allocate one dedicated channel to the consumer to avoid conflicts with the activities of other threads or code (including publishing).
- “创建消费者”意味着您告诉代理(通过连接使用通道)您希望通过该通道向您推送消息。作为响应,代理将注册您在频道上有一个消费者并开始向您推送消息。
- 通过连接推送的每条消息都将引用一个通道号和一个消费者号。这样,连接管理线程(在这种情况下,在 Java API 中)知道如何处理消息;然后,通道处理线程也知道如何处理消息。
- 消费者实现具有最广泛的变化,因为它实际上是特定于应用程序的。在我的实现中,我选择在每次有消息通过消费者到达时分拆一个任务;因此,我有一个线程管理连接,一个线程管理通道(并且通过扩展,消费者),以及通过消费者传递的每条消息的一个或多个任务线程。
- 关闭连接会关闭连接上的所有通道。关闭通道会关闭通道上的所有消费者。也可以取消消费者(不关闭通道)。在各种情况下,做这三件事中的任何一件都有意义。
- 通常,消费者在 AMQP 客户端中的实现会为消费者分配一个专用通道,以避免与其他线程或代码(包括发布)的活动发生冲突。
In terms of what you mean by consumer thread pool, I suspect that Java client is doing something similar to what I programmed my client to do (mine was based off the .Net client, but heavily modified).
就消费者线程池的含义而言,我怀疑 Java 客户端正在执行类似于我编写客户端执行的操作(我的客户端基于 .Net 客户端,但经过大量修改)。
回答by Atul Jain
There is a relation between like A TCP connection can have multiple Channels.
就像一个 TCP 连接可以有多个 Channels之间有一个关系。
Channel: It is a virtual connection inside a connection. When publishing or consuming messages from a queue - it's all done over a channel Whereas Connection: It is a TCP connection between your application and the RabbitMQ broker.
通道:它是连接内的虚拟连接。从队列发布或使用消息时 - 全部通过通道完成 而Connection:它是您的应用程序和 RabbitMQ 代理之间的 TCP 连接。
In multi-threading architecture, you may need a separate connection per thread. That may lead to underutilization of TCP connection, also it adds overhead to the operating system to establish as many TCP connections it requires during the peak time of the network. The performance of the system could be drastically reduced. This is where the channel comes handy, it creates virtual connections inside a TCP connection. It straightaway reduces the overhead of the OS, also it allows us to perform asynchronous operations in a more faster, reliable and simultaneously way.
在多线程架构中,每个线程可能需要一个单独的连接。这可能会导致 TCP 连接未得到充分利用,还会增加操作系统的开销,以便在网络高峰时间建立所需的 TCP 连接。系统的性能可能会大大降低。这是通道派上用场的地方,它在 TCP 连接内创建虚拟连接。它直接减少了操作系统的开销,还允许我们以更快、更可靠和同步的方式执行异步操作。