资源报警后 RabbitMQ 服务器上的额外 TCP 连接
Extra TCP connections on the RabbitMQ server after resource alarm
我在 Windows 上安装了 RabbitMQ Server 3.6.0(我知道是时候升级了,我已经在另一个服务器节点上完成了)。
服务器端和客户端均启用心跳(心跳间隔 60 秒)。
我有一个资源警报(RAM 限制),之后我观察到 RMQ 服务器的 TCP 连接数量增加。
目前有 18000 个连接,而正常数量是 6000。
通过管理插件我可以看到有很多连接有 0 个通道,而我们的 "normal" 连接至少有 1 个通道。
甚至 RMQ 服务器重新启动也无济于事:所有连接都将重新建立。
1. 这是否意味着他们真的都还活着?
此处描述了类似的问题 https://github.com/rabbitmq/rabbitmq-server/issues/384,但正如我所见,它已在 v3.6.0 中得到准确修复。
2. 我是否理解正确,在 RMQ 服务器 v3.6.0 之前,资源警报后的行为是这样的:每 1 个真实客户端自动恢复连接,服务器端可能会挂起多个 TCP 连接?
可能很重要:我们在服务器和客户端之间有 haProxy。
3. haProxy 可以解释这种额外的连接吗?也许它会阻止客户端收到由于资源警报而关闭连接的信号?
RabbitMQ 团队监控 this mailing list 并且有时只在 Whosebug 上回答问题。
我建议该用户从已知 TCP 连接问题的 Erlang 18 升级 -
https://groups.google.com/d/msg/rabbitmq-users/R3700QdIVJs/taDYKI6bAgAJ
- Are all of them alive?
只有你能回答这个问题,但我想问 - 你怎么会得到成千上万的连接?实际上,您应该只为每个逻辑进程创建一个连接。因此,如果您确实有 6,000 个逻辑进程连接到服务器,这可能是连接数量如此之多的原因,但在我看来,即使在这种情况下,您也远远超出了合理的设计限制。
要进行检查,请查看当您终止其中一个逻辑进程时减少了多少连接。
- Do I understand right that before RMQ Server v3.6.0 the behavior after resource alarm was like that: several TCP connections could hang on server side per 1 real client autorecovery connection?
据我所知,是的。看起来开发人员在这种情况下 运行 跨越了 common problem in sockets,这就是连接断开的检测。如果每次有人误解 TCP 的工作原理时我都能得到一美元,我的钱就会比贝索斯多。因此,他们发现有人做了一些错误的假设,当实际需要读取或写入来检测死套接字时,开发人员编写了代码(尝试)以正确处理它。重要的是要注意,这看起来不像是一个非常全面的修复,因此如果概念设计问题已被引入代码的另一部分,那么这个错误可能仍然以某种形式存在。搜索错误报告可能会为您提供更详细的答案,或者询问该支持列表中的某个人。
- Could haProxy be an explanation for this extra connections?
这取决于。从理论上讲,haProxy as 只是一种传递。连接要被代理识别,它必须经过握手,这是一个深思熟虑的过程,不会无意中发生。关闭连接也需要握手,而 haProxy 可能就是罪魁祸首。如果 haProxy 认为连接已死并在没有该过程的情况下将其丢弃,那么它可能是一个促成原因。但它本身并没有建立这些新的联系。
我已经设法重现了这个问题:最后这是我们的客户端使用 RMQ 连接的方式中的一个错误。
它创建了 1 个自动恢复连接(这很好) 和 有时它创建了一个单独的简单连接用于 "temporary" 目的。
重现我的问题的步骤是:
- 在RabbitMQ中到达内存警报(例如设置一个容易到达的RAM
限制并推送大量大消息)。连接将处于状态
"blocking".
- 开始使用这个新的 "temp" 连接从我们的客户端发送消息。
- 确保连接处于 "blocked" 状态。
- 不消除资源告警,重启RabbitMQ节点。
- "temp" 连接本身就在这里!尽管自动恢复
没有为它启用。它继续发送心跳,所以
服务器没有关闭它。
我们将修复客户端始终使用一个且唯一的连接。
另外我们当然会升级Erlang。
我在 Windows 上安装了 RabbitMQ Server 3.6.0(我知道是时候升级了,我已经在另一个服务器节点上完成了)。
服务器端和客户端均启用心跳(心跳间隔 60 秒)。
我有一个资源警报(RAM 限制),之后我观察到 RMQ 服务器的 TCP 连接数量增加。
目前有 18000 个连接,而正常数量是 6000。
通过管理插件我可以看到有很多连接有 0 个通道,而我们的 "normal" 连接至少有 1 个通道。
甚至 RMQ 服务器重新启动也无济于事:所有连接都将重新建立。
1. 这是否意味着他们真的都还活着?
此处描述了类似的问题 https://github.com/rabbitmq/rabbitmq-server/issues/384,但正如我所见,它已在 v3.6.0 中得到准确修复。
2. 我是否理解正确,在 RMQ 服务器 v3.6.0 之前,资源警报后的行为是这样的:每 1 个真实客户端自动恢复连接,服务器端可能会挂起多个 TCP 连接?
可能很重要:我们在服务器和客户端之间有 haProxy。
3. haProxy 可以解释这种额外的连接吗?也许它会阻止客户端收到由于资源警报而关闭连接的信号?
RabbitMQ 团队监控 this mailing list 并且有时只在 Whosebug 上回答问题。
我建议该用户从已知 TCP 连接问题的 Erlang 18 升级 -
https://groups.google.com/d/msg/rabbitmq-users/R3700QdIVJs/taDYKI6bAgAJ
- Are all of them alive?
只有你能回答这个问题,但我想问 - 你怎么会得到成千上万的连接?实际上,您应该只为每个逻辑进程创建一个连接。因此,如果您确实有 6,000 个逻辑进程连接到服务器,这可能是连接数量如此之多的原因,但在我看来,即使在这种情况下,您也远远超出了合理的设计限制。
要进行检查,请查看当您终止其中一个逻辑进程时减少了多少连接。
- Do I understand right that before RMQ Server v3.6.0 the behavior after resource alarm was like that: several TCP connections could hang on server side per 1 real client autorecovery connection?
据我所知,是的。看起来开发人员在这种情况下 运行 跨越了 common problem in sockets,这就是连接断开的检测。如果每次有人误解 TCP 的工作原理时我都能得到一美元,我的钱就会比贝索斯多。因此,他们发现有人做了一些错误的假设,当实际需要读取或写入来检测死套接字时,开发人员编写了代码(尝试)以正确处理它。重要的是要注意,这看起来不像是一个非常全面的修复,因此如果概念设计问题已被引入代码的另一部分,那么这个错误可能仍然以某种形式存在。搜索错误报告可能会为您提供更详细的答案,或者询问该支持列表中的某个人。
- Could haProxy be an explanation for this extra connections?
这取决于。从理论上讲,haProxy as 只是一种传递。连接要被代理识别,它必须经过握手,这是一个深思熟虑的过程,不会无意中发生。关闭连接也需要握手,而 haProxy 可能就是罪魁祸首。如果 haProxy 认为连接已死并在没有该过程的情况下将其丢弃,那么它可能是一个促成原因。但它本身并没有建立这些新的联系。
我已经设法重现了这个问题:最后这是我们的客户端使用 RMQ 连接的方式中的一个错误。 它创建了 1 个自动恢复连接(这很好) 和 有时它创建了一个单独的简单连接用于 "temporary" 目的。
重现我的问题的步骤是:
- 在RabbitMQ中到达内存警报(例如设置一个容易到达的RAM 限制并推送大量大消息)。连接将处于状态 "blocking".
- 开始使用这个新的 "temp" 连接从我们的客户端发送消息。
- 确保连接处于 "blocked" 状态。
- 不消除资源告警,重启RabbitMQ节点。
- "temp" 连接本身就在这里!尽管自动恢复 没有为它启用。它继续发送心跳,所以 服务器没有关闭它。
我们将修复客户端始终使用一个且唯一的连接。 另外我们当然会升级Erlang。