https://www.rabbitmq.com/connections.html
连接
概观
本指南涵盖与网络调整或大多数与网络相关的主题以外的连接相关的各种主题。网络和故障排除网络指南涵盖了这些内容。 channel是AMQP 0-9-1中一个密切相关的概念,也在单独的指南中有所涉及。
RabbitMQ支持多种协议:
- AMQP 0-9-1有扩展名
- AMQP 1.0
- MQTT 3.1.1
- STOMP 1.0到1.2
本指南中的许多主题同样适用于所有协议。如果情况并非如此,则指南会尝试突出显示特定于协议的功能和实践。
请注意,尽管命名方面有相似之处,但AMQP 0-9-1和AMQP 1.0是不同的协议,而不是相同协议的不同版本。
本指南包括:
和其他与连接相关的主题。
基础
应用程序使用客户端库与RabbitMQ交互。有 许多编程语言和平台可用的客户端库。每个协议都有自己的一组客户端库。大多数客户端库都是开源的。
客户端库和使用它们的应用程序在本指南中称为“客户端”。如果差异很重要,则使用更具体的术语(例如“application”)。
RabbitMQ支持的所有协议都是基于TCP的,并且假设为了效率都是基于长连接(每个协议操作不打开新连接),为了使客户端成功连接,目标RabbitMQ节点必须允许在特定协议特定端口上进行连接。
客户端连接并成功通过RabbitMQ节点进行身份验证后,它可以发布和使用消息,定义拓扑并执行协议中提供的其他操作,并由客户端库和目标RabbitMQ节点支持。
由于连接是长期存在的,因此客户端通常通过注册订阅并将消息传递(推送)到消息而不是轮询来消费消息。
当不再需要连接时,应用程序必须关闭它们以节省资源。未能做到这一点的应用程序冒着最终耗尽其目标资源节点的风险。
操作系统对单个进程可以 同时打开多少TCP连接(套接字)有一个限制。该限制通常足以用于开发和一些QA环境。 必须将生产环境配置为使用更高的限制才能支持更多的并发客户端连接。
协议差异
不同的消息协议使用不同的端口 端口也因普通TCP和TLS连接而异。该网络指南涵盖的RabbitMQ取决于什么协议都被启用,TLS是否使用等使用的所有端口。
AMQP 0-9-1
AMQP 0-9-1提供了通过单个TCP连接进行多路复用连接的方法。这意味着应用程序可以在单个连接上打开多个称为通道的“轻量级连接”。AMQP 0-9-1客户端在连接后打开一个或多个通道,并在通道上执行协议操作(管理拓扑,发布,使用)。
AMQP 1.0
AMQP 1.0提供了通过单个TCP连接进行多路复用连接的方法。这意味着应用程序可以在单个连接上打开多个称为会话的“轻量级连接”。然后,应用程序设置一个或多个链接以发布和使用消息。
连接生命周期
为了让客户端与RabbitMQ进行交互,必须首先打开一个连接。此过程涉及许多步骤:
- 应用程序配置它用于使用某个连接端点的客户端库(例如主机名和端口)
- 该库将主机名解析为一个或多个IP地址
- 该库打开与目标IP地址和端口的TCP连接
- 服务器接受TCP连接后,将执行协议特定的协商过程
- 然后,服务器验证客户端
- 客户端现在可以执行操作,每个操作都涉及服务器的授权检查。
此流程在协议与协议之间没有显着变化,但存在细微差别。
协议差异
AMQP 0-9-1
AMQP 0-9-1有一个包含连接和通道的模型。通道允许连接多路复用(在“物理”或TCP上具有多个逻辑连接)。
可以在连接上同时打开的最大通道数由客户端和服务器在连接时协商。无法将客户端配置为允许比服务器配置的最大通道数更多的通道。
在成功打开连接并进行身份验证后,应用程序会打开一个或多个通道并使用它们执行协议操作,例如定义拓扑,使用和发布消息。
AMQP 0-9-1支持不同的身份验证机制。尽管应用程序提供一对凭证是最常见的,但可以使用 x509证书和PKI 。
AMQP 1.0
AMQP 1.0有一个包含连接,会话和链接的模型。
成功打开连接并进行身份验证后,应用程序将打开一个或多个会话。然后,它会附加到会话的链接,以便发布和使用消息。
MQTT 3.1
MQTT 3.1连接遵循上述流程。MQTT支持可选的身份验证。使用它时,RabbitMQ使用一组预先配置的凭据。
STOMP
STOMP连接遵循上述流程。
记录
RabbitMQ记录发送至少1个字节数据的所有入站客户端连接。将不记录在没有任何活动的情况下打开的连接。这是为了防止TCP负载均衡器运行状况检查泛滥日志。
还将记录成功的身份验证,干净和意外的连接关闭。
“ 日志记录”指南中更详细地介绍了此主题。
监控
当前打开的客户端连接数和连接打开/关闭率是应该监视的系统的重要度量标准。监视它们将有助于检测基于消息传递的系统中常见的许多问题:
- 连接泄漏
- 高连接流失。
这两个问题最终导致节点耗尽资源。
连接泄漏
连接泄漏是应用程序重复打开连接而不关闭它们或至少只关闭其中一些连接的条件。
连接泄漏最终耗尽文件句柄的节点(或多个目标节点),这意味着将拒绝任何新的入站客户端,对等或CLI工具连接。并发连接数的增加也会增加节点的内存消耗。
相关指标
管理UI提供了集群范围内打开的连接总数的图表:
监控图表上的连接泄漏可以被识别为单调增长的客户端连接数。
还可以查看特定节点有多少文件句柄和套接字,这对于确定连接泄漏也很有用。下图演示了节点上打开的非常稳定的套接字数量:
此图表显示了丢弃后单调增加的连接数:
如果节点使用的套接字数量不断增长和增长,则可能表明其中一个应用程序发生了连接泄漏。
某些客户端库(例如Java客户端)公开指标,包括当前打开的连接数。围绕连接绘制和监控应用程序指标是确定哪些应用程序泄漏连接或以次优方式使用它们的最佳方法。
在许多使用长寿命连接并且不泄漏它们的应用程序中,连接数量会在应用程序启动时增加,然后会缓和(保持大部分稳定且波动很小)。
管理UI提供了有关RabbitMQ 3.7.9的新打开连接速率的图表。下面的图表显示了相当低的新连接率:
高连接流失
当一个系统的新连接速率一直很高并且其闭合连接速率一直很高时,据说该系统具有高连接流失。这通常意味着应用程序使用短期连接。虽然对于某些工作负载而言这是系统的自然状态,但应尽可能使用长寿命连接。
管理UI提供了RabbitMQ 3.7.9的连接流失率图表。下面的图表显示了一个相当低的连接流失率,在给定的时间段内打开和关闭的连接数量相当:
虽然连接和断开速率是系统特定的,但速率始终高于100 /秒可能表示一个或多个应用程序的连接管理不是最理想,通常值得研究。
请注意,某些客户端和运行时(特别是PHP)不使用长期连接,并且除非使用专用代理,否则期望它们具有高连接流失率。
遇到高连接流失的环境需要TCP堆栈调整以避免资源耗尽。网络指南中对此进行了介绍。
资源使用
每个连接都消耗目标RabbitMQ节点上的内存和一个文件句柄。
大多数内存由连接的TCP缓冲区使用。它们的大小可以 显着减小,从而导致显着的每连接内存消耗,同时降低连接吞吐量。
RabbitMQ节点可以打开的最大文件句柄数受内核限制,必须引发才能支持大量连接。
支持大量连接
在某些环境中,拥有大量并发连接的客户端是很自然的。例如,涉及大量硬件客户端(物联网,物联网工作负载)的系统从第一天就可以拥有数千个客户端。
由于连接消耗资源,因此维持大量并发连接需要减少资源消耗或配置更多资源或节点。在实践中,这两个选项组合使用。
该网络导向具有专用于部分地自动调节为大量的并发连接。
TLS
可以使用TLS加密客户端连接。TLS还可以用作验证客户端的附加或主要方式。在TLS指南中了解更多信息。
流量控制
发布消息的连接可能超过系统的其他部分,很可能是繁忙的队列和执行复制的队列。发生这种情况时,流控制将应用于发布连接。仅使用消息的连接不受应用于发布者的流控制的影响。
对于使用自动确认模式的较慢的消费者, 当写入TCP套接字时,连接和通道很可能会遇到流量控制。
监控系统可以收集有关流状态的连接数的指标。定期体验流控制的应用程序可能会考虑使用单独的连接来发布和使用,以避免流量控制对非发布操作的影响(例如队列管理)。
错误处理和协议异常
连接可能失败或无法满足客户端操作。这种情况称为错误或协议异常。它们可以指示瞬态条件(例如,资源被锁定),语义问题或协议实现(例如,不正确的框架)。
消息传递协议中的大多数错误都被认为是不可恢复的。请注意,协议错误与网络连接故障不同。
协议差异
AMQP 0-9-1
在AMQP 0-9-1中,连接错误用于传达不可恢复(“硬”)错误,例如错误的成帧或连接状态违规。例如,如果具有相同ID(编号)的通道被多次打开。向客户端发送错误后,将关闭连接。
可以使用通道异常(“软错误”)传达可以纠正和重试的错误。
AMQP 1.0
在AMQP 1.0中,大多数错误都属于会话错误或 链接错误。会话错误是不可恢复的,并且导致检测到错误的对等方接收到的所有操作被丢弃直到会话终止。
链接错误仅限于特定链接。由于链接可以在不影响其会话的情况下进行附加和重新连接,因此实际应用程序可以在更正根本原因(如果可能)后重试失败的操作。
STOMP
在STOMP中,服务器通过发送ERROR帧 和关闭TCP连接来传达错误。该框架将在消息字段中包含错误消息。
MQTT 3.1
在MQTT 3.1中,服务器将错误传达给客户端的方式有限。主要方法是关闭客户端的TCP连接。这为开发人员提供的上下文和可见性有限。这是MQTT 3.1设计的基本限制。
MQTT客户端通常配置为自动重新连接和重试操作,可能会创建错误触发循环,连接风暴和雷鸣群问题的变化。
从网络连接失败中恢复
客户端的TCP连接可能会失败或遇到严重的数据包丢失,这会使RabbitMQ节点认为它们不可用。
某些客户端库提供了一种从网络连接故障中自动恢复的机制。 例如,RabbitMQ Java客户端和RabbitMQ .NET客户端支持此类功能。此功能主要是协议和客户端库。
其他客户端可能会认为网络故障恢复是应用程序的责任。在这种情况下,它们通常提供包含连接和拓扑恢复的示例。