https://www.rabbitmq.com/troubleshooting-networking.html
网络连接故障排除
概观
本指南伴随着一个关于网络,侧重于网络连接的troublshooting。
对于使用TLS的连接,还有一个有关TLS故障排除的附加指南。
故障排除方法
网络连接问题的故障排除是一个广泛的主题。有关于它的全书。本指南介绍了一种方法和广泛可用的网络工具,可帮助缩小最常见的问题。
网络协议是分层的。他们的问题也是如此。有效的故障排除策略通常使用消除过程来确定问题(或多个问题),从较高级别开始。特别是对于消息传递技术,以下步骤通常是有效且充分的:
- 验证客户端配置
- 使用rabbitmq-diagnostics侦听器, rabbitmqctl status,rabbitmqctl环境验证服务器配置
- 检查服务器日志
- 验证主机名解析
- 验证使用的 TCP 端口及其可访问性
- 验证IP路由
- 如果需要,采取并分析流量转储(流量捕获)
这些步骤按顺序执行时,通常有助于确定绝大多数网络问题的根本原因。低于Internet(网络)层级别的故障排除工具和技术 不在本指南的讨论范围之内。
某些问题仅发生在具有高度连接流失的环境中。可以使用管理UI检查客户端连接。还可以检查节点的所有TCP连接及其状态。随着时间的推移收集的信息与服务器日志相结合,将有助于检测连接流失,文件描述符耗尽和相关问题。
验证客户端配置
所有开发人员和运营商都在那里:拼写错误,过时的值,供应工具中的问题,混合的公钥和私钥路径等等。第一步是仔细检查应用程序和客户端库配置。
验证服务器配置
验证服务器配置有助于证明RabbitMQ正在运行与网络相关的预期设置集。它还验证节点实际上是否正在运行。以下是建议的步骤:
- 确保节点正在使用rabbitmqctl status运行
- 验证配置文件已正确放置并具有正确的语法/结构
- Inspect listeners using rabbitmq-diagnostics listeners or the listeners section in rabbitmqctl status
- 使用 rabbitmqctl environment 检查有效配置
听众部分看起来像这样:
Interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Interface: [::], port: 5671, protocol: amqp/ssl, purpose: AMQP 0-9-1 and AMQP 1.0 over TLS
Interface: [::], port: 15672, protocol: http, purpose: HTTP API
Interface: [::], port: 15671, protocol: https, purpose: HTTP API over TLS (HTTPS)
Interface: [::], port: 1883, protocol: mqtt, purpose: MQTT
在上面的示例中,节点上有6个TCP侦听器:
- 端口25672上的节点间和CLI工具通信
- AMQP 0-9-1(以及1.0,如果已启用)侦听器,用于端口5672上的非TLS连接
- AMQP 0-9-1(以及1.0,如果已启用)侦听器,用于端口5671上启用TLS的连接
- 端口15672(HTTP)和15671(HTTPS)上的HTTP API侦听器
- 用于非TLS连接的MQTT侦听器1883
使用rabbitmqctl状态,它将如下所示:
% ...
{listeners,
[{clustering,25672,"::"},
{amqp,5672,"::"},
{'amqp/ssl',5671,"::"},
{http,15672,"::"}]}
% ...
在第二个示例中,节点上有4个TCP侦听器:
- 节点间和CLI工具通信端口,25672
- AMQP 0-9-1(以及1.0,如果已启用)非TLS连接的监听器,5672
- AMQP 0-9-1(以及1.0,如果已启用)侦听器,用于启用TLS的连接,5671
- 端口15672上的HTTP API侦听器(仅限HTTP)
所有侦听器都绑定到所有可用接口。
检查节点使用的TCP侦听器有助于发现非标准端口配置,应该配置但不是的协议插件(例如MQTT),节点仅限于少数网络接口的情况,等等。如果端口不在侦听器列表中,则表示节点无法接受其上的任何连接。
检查服务器日志
RabbitMQ节点将记录关键客户端连接生命周期事件。必须成功建立TCP连接,并且对等方必须至少发送1个字节的数据才能将连接视为(并记录为)接受。如果未记录任何事件,则表示没有成功的TCP连接或者没有发送任何数据。
主机名解析
应用程序在连接到RabbitMQ时使用主机名或URI与主机名是很常见的。dig和nslookup是用于解决主机名解析的常用工具。
端口访问
除主机名解析和IP路由问题外,外部连接的TCP端口不可访问性是客户端连接失败的常见原因。telnet是一种常用的非常简约的工具,用于测试与特定主机名和端口的TCP连接。
以下示例使用telnet连接到端口5672上的主机localhost。有一个运行节点,在localhost上运行库存默认值,没有任何东西阻止访问该端口,因此连接成功。然后输入12345进行输入,然后输入。由于12345不是正确的AMQP协议头,因此服务器关闭TCP连接:
telnet localhost 5672
# => Trying ::1...
# => Connected to localhost.
# => Escape character is '^]'.
12345 # enter this and hit Enter to send
# => AMQP Connection closed by foreign host.
在telnet连接成功后,使用Control +]然后使用Control + D退出它。
以下示例连接到端口5673上的localhost。连接失败(由操作系统拒绝),因为没有进程侦听该端口。
telnet localhost 5673
# => Trying ::1...
# => telnet: connect to address ::1: Connection refused
# => Trying 127.0.0.1...
# => telnet: connect to address 127.0.0.1: Connection refused
# => telnet: Unable to connect to remote host
telnet连接失败或超时强烈建议有一个代理,负载均衡器或防火墙阻止目标端口上的传入连接。这也可能是由于RabbitMQ进程未在目标节点上运行或使用非标准端口。应该在双重检查服务器侦听器配置的步骤中消除这些场景。
有大量的防火墙,代理和负载均衡器工具和产品。 iptables是Linux和其他类UNIX系统上常用的防火墙。 Web上不缺少iptables教程。
可以使用netstat, ss,lsof检查节点的开放端口,TCP和UDP连接。
以下示例使用lsof显示侦听端口5672并使用IPv4的OS进程:
sudo lsof -n -i4TCP:5672 | grep LISTEN
同样,对于使用IPv6的程序:
sudo lsof -n -i6TCP:5672 | grep LISTEN
在1883号港口:
sudo lsof -n -i4TCP:1883 | grep LISTEN
sudo lsof -n -i6TCP:1883 | grep LISTEN
如果上述命令不产生输出,则没有本地OS进程侦听给定端口。
以下示例使用ss显示使用IPv4及其操作系统进程的侦听TCP套接字:
sudo ss --tcp -f inet --listening --numeric --processes
同样,对于使用IPv6的TCP套接字:
sudo ss --tcp -f inet6 --listening --numeric --processes
有关RabbitMQ及其各种插件使用的端口列表,请参见上文。通常,防火墙和代理必须允许用于外部连接的所有端口。
rabbitmq-diagnostics侦听器和rabbitmqctl状态可用于列出RabbitMQ节点上已启用的侦听器及其端口。
IP路由
RabbitMQ支持的消息传递协议使用TCP,并要求客户端和RabbitMQ主机之间的IP路由正常运行。有几种工具和技术可用于验证两台主机之间的IP路由。traceroute和ping 是许多操作系统可用的两种常用选项。大多数路由表检查工具都是特定于操作系统的
请注意,traceroute和ping都使用ICMP, 而RabbitMQ客户端库和节点间连接使用TCP。因此,单独成功执行ping操作并不能保证客户端连接成功。
Both traceroute and ping have Web-based and GUI tools built on top.
捕获流量
可以使用流量捕获检查,过滤和分析所有网络活动。
tcpdump及其GUI兄弟Wireshark 是捕获流量,过滤和分析的行业标准。两者都支持RabbitMQ支持的所有协议。有关概述,请参阅使用Wireshark with RabbitMQ指南。
TLS连接
对于使用TLS的连接,有一个单独的TLS故障排除指南。
采用TLS时,务必确保客户端使用正确的端口进行连接(请参阅上面的端口列表)并指示他们使用TLS(执行TLS升级)。未配置为使用TLS的客户端将成功连接到启用TLS的服务器端口,但其连接将超时,因为它从未执行服务器所需的TLS升级。
连接到启用非TLS的端口的启用TLS的客户端将成功连接并尝试执行服务器不期望的TLS升级,这会触发协议解析器异常。服务器将记录此类异常。
检查连接
可以使用netstat, ss,lsof检查节点的开放端口,TCP和UDP连接。
以下示例使用netstat列出所有TCP连接套接字,而不管其状态和接口如何。IP地址将显示为数字,而不是解析为域名。程序名称将打印在数字端口值旁边(与协议名称相对)。
sudo netstat --all --numeric --tcp --programs
可以通过这种方式检查入站(客户端,对等节点,CLI工具)和传出(对等节点,联合链接和铲子)连接。
rabbitmqctl list_connections和管理UI可用于检查更多连接属性,其中一些属性是RabbitMQ或特定于消息传递协议:
- 网络流量,包括入站和出站
- 使用消息传递(应用程序级)协议
- 连接虚拟主机
- 连接时间
- 用户名
- 频道数量
- 客户端库详细信息(名称,版本,功能)
- 有效的心跳超时
- TLS详细信息
将管理UI或CLI工具的连接信息与netstat或ss的连接信息相结合, 可以帮助解决行为不当的应用程序,应用程序实例和客户端库。
检测高连接流失
高连接流失(许多连接在短时间内打开和关闭)可能导致资源耗尽。因此,能够识别这种情况很重要。netstat和ss 是检查TCP连接的最常用选项。TIME_WAIT状态下的许多连接可能是高连接流失的症状。除了ESTABLISHED之外的其他state的许多联系也可能是值得研究的症状。
可以在RabbitMQ日志文件中找到短期连接的证据。例如,这是一个持续时间仅为几毫秒的连接示例:
2018-06-17 16:23:29.851 [info] <0.634.0> accepting AMQP connection <0.634.0> (127.0.0.1:58588 -> 127.0.0.1:5672)
2018-06-17 16:23:29.853 [info] <0.634.0> connection <0.634.0> (127.0.0.1:58588 -> 127.0.0.1:5672): user 'guest' authenticated and granted access to vhost '/'
2018-06-17 16:23:29.855 [info] <0.634.0> closing AMQP connection <0.634.0> (127.0.0.1:58588 -> 127.0.0.1:5672, vhost: '/', user: 'guest')