61

我是 Rabbitmq(和编程)的新手,如果这很明显,请提前抱歉。我正在创建一个池以在队列上工作的线程之间共享,但我不确定是否应该使用池中的连接或通道。

我知道我需要通道来完成实际工作,但是每个连接有一个通道是否有性能优势(就队列的更多吞吐量而言)?还是我最好只为每个应用程序使用一个连接并汇集许多通道?

注意:因为我正在集中资源,所以初始成本不是一个因素,因为我知道连接比通道更昂贵。我对吞吐量更感兴趣。

4

3 回答 3

86

我在rabbitmq 网站上找到了这个,它靠近底部,所以我在下面引用了相关部分。

tl;dr 版本是每个应用程序应该有 1 个连接,每个线程应该有 1 个通道。希望有帮助。

连接

AMQP 连接通常是长期存在的。AMQP 是一种应用层协议,它使用 TCP 进行可靠传输。AMQP 连接使用身份验证,并且可以使用 TLS (SSL) 进行保护。当应用程序不再需要连接到 AMQP 代理时,它应该优雅地关闭 AMQP 连接,而不是突然关闭底层 TCP 连接。

频道

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

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

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

建议每个线程有 1 个通道,即使它们是线程安全的,所以您可以让多个线程通过一个通道发送。就您的应用程序而言,我建议您坚持每个线程使用 1 个通道。

此外,建议每个频道只有 1 个消费者。

这些只是指导方针,因此您必须进行一些测试以查看最适合您的方法。

这个线程在这里这里有一些见解。

尽管有所有这些指导方针,但这篇文章表明它很可能不会因拥有多个连接而影响性能。虽然它是在谈论客户端还是服务器(rabbitmq)端并没有具体说明。一方面,它当然会使用更多的系统资源和更多的连接。如果这不是问题并且您希望获得更高的吞吐量,那么像这篇文章那样拥有多个连接确实会更好建议多个连接将允许您更高的吞吐量。原因似乎是即使有多个通道,一次也只有一条消息通过连接。因此,一条大消息将阻塞整个连接,或者一个通道上的许多不重要消息可能会阻塞同一连接但不同通道上的重要消息。资源又是一个问题。如果您通过一个连接用尽所有带宽,那么添加一个额外的连接不会比在一个连接上拥有两个通道提高性能。此外,每个连接都将使用更多的内存、cpu 和文件句柄,但这可能不是问题,尽管在扩展时可能是一个问题。

于 2012-05-08T15:22:36.110 回答
15

除了接受的答案:

如果你有一个 RabbitMQ 节点集群,前面有一个负载均衡器,或者一个短期 DNS(使得每次都可以连接到不同的 rabbit 节点),那么一个单一的长期连接将意味着一个应用程序节点专门与单个 RabbitMQ 节点一起工作。这可能会导致一个 RabbitMQ 节点的使用率高于其他节点。

上面提到的另一个问题是发布和消费都是阻塞操作,这会导致消息排队。拥有更多连接将确保 1. 每条消息的处理时间不会阻塞其他消息 2. 大消息不会阻塞其他消息。

这就是为什么值得考虑拥有一个小型连接池的原因(考虑到上面提出的资源问题)

于 2014-06-11T11:50:18.113 回答
1

“每个线程一个通道”可能是一个安全的假设(我说可能是因为我自己没有进行任何研究,我没有理由怀疑文档:))但请注意,在某些情况下会出现这种情况:

如果您将 RPC 与 RabbitMQ直接回复一起使用,那么您将无法重用相同的通道来消费另一个RPC 请求。我在google 用户组中询问了有关此问题的详细信息,我从 Michael Klishin(他似乎积极参与 RabbitMQ 开发)那里得到的答案是

无论哪种方式,直接回复都不意味着与频道共享一起使用。

我已通过电子邮件向 Pivotal 发送电子邮件以更新他们的文档,以解释其背后的工作原理 amq.rabbitmq.reply-to,但我仍在等待答复(或更新)。

因此,如果您想坚持“每个线程一个频道”,请注意,因为这不适用于直接回复。

于 2017-10-30T20:03:18.480 回答