https://www.rabbitmq.com/networking.html
网络和RabbitMQ
介绍
客户端通过网络与RabbitMQ进行通信。broker支持的所有协议都是基于TCP的。RabbitMQ和操作系统都提供了许多可以调整的旋钮。其中一些与TCP和IP操作直接相关,另一些与应用程序级协议(如TLS)有关。本指南涵盖了与RabbitMQ环境中的网络相关的多个主题。本指南并不是一个详细介绍参考,而是一个概述。讨论的一些可调参数是特定于OS的。本指南在介绍特定于操作系统的主题时侧重于Linux,因为它是部署RabbitMQ的最常见平台。
有几个区域可以配置或调整:
- 接口
- 客户端使用的端口,集群中的节点间流量和CLI工具
- 用于客户端连接的TLS
- TCP缓冲区大小(影响吞吐量和每个连接使用的内存量)
- 其他TCP套接字设置
- 代理协议支持客户端连接
- 内核TCP设置和限制(例如TCP keepalive和打开文件句柄限制)
- (AMQP 0-9-1,STOMP)心跳,在MQTT中称为keepalives
- 主机名,主机名解析和DNS
除OS内核参数和DNS外,所有RabbitMQ设置均通过RabbitMQ配置文件进行配置。
网络是一个广泛的主题。有许多配置选项可能会对某些工作负载产生正面或负面影响。因此,本指南不会尝试成为完整的参考,而是提供关键可调参数的索引并作为起点。
此外,本指南还涉及与网络密切相关的一些主题,例如连接生命周期日志记录,代理和负载平衡器,高连接流失和资源耗尽等。网络相关问题的故障排除方法 在单独的指南中介绍。
网络接口
对于RabbitMQ接受客户端连接,它需要绑定到一个或多个接口并侦听(特定于协议的)端口。使用rabbit.tcp_listeners配置选项配置接口。默认情况下,RabbitMQ将在所有可用接口上侦听端口5672。
TCP侦听器配置接口和端口。以下示例演示如何在特定IP和标准端口上配置RabbitMQ:
listeners.tcp.1 = 192.168.1.99:5672
或使用经典配置格式:
[
{rabbit, [
{tcp_listeners, [{"192.168.1.99", 5672}]}
]}
].
侦听双栈(IPv4和IPv6)接口
以下示例演示如何将RabbitMQ配置为仅针对IPv4和IPv6侦听localhost:
listeners.tcp.1 = 127.0.0.1:5672
listeners.tcp.2 = ::1:5672
或者,在经典的配置格式中:
[
{rabbit, [
{tcp_listeners, [{"127.0.0.1", 5672},
{"::1", 5672}]}
]}
].
使用Vista之后的现代Linux内核和Windows版本,当指定端口并且RabbitMQ配置为侦听所有IPv6地址但未明确禁用IPv4时,将包含IPv4地址,因此
listeners.tcp.1 = :::5672
相当于
listeners.tcp.1 = 0.0.0.0:5672
listeners.tcp.2 = :::5672
在经典的配置格式中:
[
{rabbit, [
{tcp_listeners, [{"::", 5672}]}
]}
].
相当于
[
{rabbit, [
{tcp_listeners, [{"0.0.0.0", 5672},
{"::", 5672}]}
]}
].
仅侦听IPv4接口
在此示例中,RabbitMQ仅侦听IPv4接口:
listeners.tcp.1 = 192.168.1.99:5672
在经典的配置格式中:
[
{rabbit, [
{tcp_listeners, [{"192.168.1.99", 5672}]}
]}
].
或者,如果需要单个堆栈设置,则可以使用RABBITMQ_NODE_IP环境变量配置接口。请参阅我们的配置指南以了解detalis。
仅侦听IPv6接口
在此示例中,RabbitMQ仅侦听IPv6接口:
listeners.tcp.1 = fe80::2acf:e9ff:fe17:f97b:5672
在经典的配置格式中:
[
{rabbit, [
{tcp_listeners, [{"fe80::2acf:e9ff:fe17:f97b", 5672}]}
]}
].
或者,如果需要单个堆栈设置,则可以使用RABBITMQ_NODE_IP环境变量配置接口。请参阅我们的配置指南以了解detalis。
端口访问
RabbitMQ节点绑定到端口(打开服务器TCP套接字)以接受客户端和CLI工具连接。其他进程和工具(如SELinux)可能会阻止RabbitMQ绑定到端口。发生这种情况时,节点将无法启动。CLI工具,客户端库和RabbitMQ节点也打开连接(客户端TCP套接字)。防火墙可以防止节点和CLI工具相互通信。确保可以访问以下端口:
- 4369:epmd,RabbitMQ节点和CLI工具使用的对等发现服务
- 5672,5671:AMQP 0-9-1和1.0客户端使用没有和使用TLS
- 25672:用于节点间和CLI工具通信(Erlang分发服务器端口),并从动态范围分配(默认情况下限于单个端口,计算为AMQP端口+ 20000)。除非确实需要这些端口上的外部连接(例如,群集使用联合或CLI工具在子网外的计算机上使用),否则不应公开这些端口。有关详情, 请参阅网络指南
- 35672-35682:由CLI工具(Erlang分发客户端端口)用于与节点通信,并从动态范围(计算为服务器分发端口+ 10000到服务器分发端口+ 10010)进行分配。有关详情, 请参阅网络指南
- 15672:HTTP API客户端,管理UI和rabbitmqadmin(仅当启用了管理插件时)
- 61613,61614:没有和使用TLS的STOMP客户端(仅当启用了STOMP插件时)
- 1883,8883 :( 如果启用了MQTT插件,则没有和使用TLS的MQTT客户端
- 15674:STOMP-over-WebSockets客户端(仅当启用了Web STOMP插件时)
- 15675:MQTT-over-WebSockets客户端(仅当启用了Web MQTT插件时)
可以将RabbitMQ配置 为使用不同的端口和特定的网络接口。
EPMD和节点间通信端口
Erlang使用Port Mapper Daemon(epmd)来解析集群中的节点名称。默认的epmd端口是4369,但可以使用ERL_EPMD_PORT环境变量进行更改。所有节点必须使用相同的端口。
一旦通过epmd解析了分布式Erlang节点地址,其他节点将尝试使用Erlang分发协议直接与该地址通信。
RabbitMQ节点使用称为分发端口的端口与CLI工具和其他节点进行通信。它是从一系列值动态分配的。对于RabbitMQ,默认范围限制为计算为RABBITMQ_NODE_PORT(AMQP端口)+ 20000 的单个值 ,这将导致使用端口25672.可以 使用RABBITMQ_DIST_PORT环境变量配置此单个端口。
RabbitMQ 命令行工具 也使用一系列端口。通过获取RabbitMQ分发端口值并向其添加10000来计算默认范围。接下来的10个端口也是该系列的一部分。因此,默认情况下,此范围为35672到35682.可以使用RABBITMQ_CTL_DIST_PORT_MIN 和RABBITMQ_CTL_DIST_PORT_MAX环境变量配置此范围。请注意,将范围限制为单个端口将阻止多个CLI工具在同一主机上并发运行,并且可能会影响需要并行连接到多个群集节点的CLI命令。因此,端口范围为10是建议值。
配置防火墙规则时,强烈建议允许来自每个集群成员和可能使用CLI工具的每个主机的节点间通信端口上的远程连接。必须打开epmd端口才能使CLI工具和群集正常运行。
RabbitMQ使用的范围也可以通过两个配置键控制:
- kernel.inet_dist_listen_min在经典配置格式只
- kernel.inet_dist_listen_max在经典配置格式只
它们定义了范围的下限和上限,包括在内。
以下示例使用具有单个端口的范围,但值与默认值不同:
[
{kernel, [
{inet_dist_listen_min, 33672},
{inet_dist_listen_max, 33672}
]},
{rabbit, [
...
]}
].
要验证节点使用哪个端口进行节点间和CLI工具通信,请运行
epmd -names
在该节点的主机上。它将产生如下所示的输出:
epmd: up and running on port 4369 with data:
name rabbit at port 25672
epmd默认会监听所有接口。它可以使用ERL_EPMD_ADDRESS 环境变量限制为许多接口。loopback接口将隐式添加到该列表中(换句话说,epmd将始终绑定到loopback接口)。
See the Erlang epmd man page to learn more about epmd.
节点间通信缓冲区大小限制
节点间连接使用缓冲区来发送待处理的数据。当缓冲区处于最大允许容量时,将应用节点间流量的临时限制。该限制是通过RABBITMQ_DISTRIBUTION_BUFFER_SIZE 环境变量( 以KB 为单位)控制的。默认值为128 MB(128000 kB)。
在具有大量节点间流量的群集中,此值可能对吞吐量产生积极影响。建议不要使用低于64 MB的值。
中介:代理和负载均衡器
代理和负载平衡器通常用于在群集节点之间分发客户端连接。代理也可以使客户端访问RabbitMQ节点而不公开暴露它们。中介也可能对连接产生副作用。
代理效应
代理和负载平衡器在客户端与其目标节点之间引入额外的网络跃点(甚至多个网络跃点)。中介也可能成为网络争用点:它们的吞吐量将成为整个系统的限制因素。因此,代理和负载平衡器的网络带宽过度配置和吞吐量监控非常重要。
中间人也可以在一段时间内没有活动时终止“空闲”TCP连接。大多数时候,这是不可取的。此类事件将导致 服务器端的突发连接关闭日志消息和客户端上的I / O异常。
在连接上启用心跳时,会导致周期性的轻型网络流量。因此,心跳具有保护客户端连接的副作用,这些客户端连接可以在一段时间内空闲,以防止代理和负载平衡器过早关闭。
从10到30秒的心跳超时将产生足够频繁的网络流量(大约每5到15秒),以满足大多数代理工具和负载平衡器的默认值。过低的值会产生误报。
代理协议
RabbitMQ支持 代理协议。当连接通过代理(例如HAproxy或AWS ELB)时,该协议使RabbitMQ等服务器知道实际的客户端IP地址。这使操作员可以更轻松地检查管理UI或CLI工具中的连接源。
协议规范要求必须将其应用于所有连接,或者出于安全原因而不应用于所有连接,默认情况下禁用此功能,并且需要为RabbitMQ支持的各个协议启用此功能。要为AMQP 0-9-1和AMQP 1.0客户端启用它:
proxy_protocol = true
或者,使用经典配置格式:
[
{rabbit, [
{proxy_protocol, true}
]}
].
启用代理协议后,客户端将无法直接连接到RabbitMQ,除非它们自己支持该协议。因此,启用此选项后,所有客户端连接都必须通过也支持该协议的代理,并配置为发送代理协议头。HAproxy 和AWS ELB文档说明了如何执行此操作。
启用代理协议并且连接通过兼容代理时,客户端库不需要任何操作或修改。沟通对他们来说完全透明。
STOMP和 MQTT以及 Web STOMP和 Web MQTT 都有自己的设置,支持代理协议。
TLS(SSL)支持
可以使用带有RabbitMQ的TLS加密连接。也可以使用对等证书进行身份验证。 有关更多信息,请参阅TLS / SSL指南。
吞吐量调优
调整吞吐量是一个共同的目标。可以通过以下方式实现改进
- 增加TCP缓冲区大小
- 确保禁用Nagle的算法
- 启用可选的TCP功能和扩展
对于后两者,请参阅下面的操作系统级调整部分。请注意,调整吞吐量将涉及权衡。例如,增加TCP缓冲区大小将增加每个连接使用的RAM量,这可能是服务器RAM使用量的显着增加。
TCP缓冲区大小
这是关键的可调参数之一。每个TCP连接都有为其分配的缓冲区。一般来说,这些缓冲区越大,每个连接使用的RAM越多,吞吐量越高。在Linux上,操作系统默认会自动调整TCP缓冲区大小,通常会设置在80到120 KB之间的值。为了获得最大吞吐量,可以使用rabbit.tcp_listen_options,rabbitmq_mqtt.tcp_listen_options, rabbitmq_amqp1_0.tcp_listen_options和相关的配置密钥来增加缓冲区大小 。请注意,增加TCP缓冲区大小将直接转换为节点的更高RAM使用率。
以下示例将AMQP 0-9-1连接的TCP缓冲区设置为192 KiB:
tcp_listen_options.backlog = 128
tcp_listen_options.nodelay = true
tcp_listen_options.linger.on = true
tcp_listen_options.linger.timeout = 0
tcp_listen_options.sndbuf = 196608
tcp_listen_options.recbuf = 196608
在经典的配置格式中:
[
{rabbit, [
{tcp_listen_options, [
{backlog, 128},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false},
{sndbuf, 196608},
{recbuf, 196608}
]}
]}
].
MQTT和STOMP连接的相同示例:
[
{rabbitmq_mqtt, [
{tcp_listen_options, [
{backlog, 128},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false},
{sndbuf, 196608},
{recbuf, 196608}
]}
]},
{rabbitmq_stomp, [
{tcp_listen_options, [
{backlog, 128},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false}
{sndbuf, 196608},
{recbuf, 196608}
]}
]}
].
请注意,将发送和接收缓冲区大小设置为不同的值是危险的,不建议这样做。
Erlang VM I / O线程池
Erlang运行时使用一个线程池来异步执行I / O操作。池的大小是通过RABBITMQ_IO_THREAD_POOL_SIZE环境变量配置的。该变量是设置+ A VM命令行标志的快捷方式,例如+ A 128。
# reduces number of I/O threads from 128 to 32
RABBITMQ_IO_THREAD_POOL_SIZE=32
要直接设置标志,请使用`RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS`环境变量:
RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="+A 128"
最近的RabbitMQ版本中的默认值是128(之前为30)。建议使用具有8个或更多内核的节点使用高于96的值,即每个可用内核的12个或更多I / O线程。请注意,较高的值并不一定意味着由于等待I / O而导致更高的吞吐量或更低的CPU损耗。
基于大量连接的调优方法
一些工作负载(通常称为“物联网”)假设每个节点有大量客户端连接,并且来自每个节点的流量相对较低。一个这样的工作负载是传感器网络:可以部署数十万或数百万个传感器,每个传感器每隔几分钟发送一次数据。优化最大并发客户端数量可能比总吞吐量更重要。
有几个因素可以限制单个节点可以支持的并发连接数:
打开文件句柄限制
大多数操作系统限制可以同时打开的文件句柄数。当OS进程(例如RabbitMQ的Erlang VM)达到限制时,它将无法打开任何新文件或接受任何更多TCP连接。
如何配置限制因OS和OS以及分发而异,例如取决于是否使用systemd。对于Linux,我们在Debian和RPM 安装指南中提供了Linux上的控制系统限制。Linux内核限制管理由Web上的许多资源覆盖,包括打开文件句柄限制。
使用Docker, 主机中的Docker守护程序配置文件控制限制。
MacOS使用类似的系统。
在Windows上,使用ERL_MAX_PORTS环境变量控制Erlang运行时的限制。
在优化并发连接数时,确保您的系统有足够的文件描述符,不仅支持客户端连接,还支持节点可能使用的文件。要计算球场限制,请将每个节点的连接数乘以1.5。例如,要支持100,000个连接,请将限制设置为150,000。增加限制会略微增加RAM闲置机器的使用量,但这是一个合理的权衡。
每个连接内存消耗:TCP缓冲区大小
请参阅上面的部分以获取概述。可以使用rabbit.tcp_listen_options,rabbitmq_mqtt.tcp_listen_options, rabbitmq_amqp1_0.tcp_listen_options和相关的配置键来减小缓冲区大小 , 以减少每个连接使用的服务器的RAM量。在每个节点维持的并发连接数比吞吐量更重要的环境中,这通常是必需的。
以下示例将AMQP 0-9-1连接的TCP缓冲区设置为32 KiB:
tcp_listen_options.backlog = 128
tcp_listen_options.nodelay = true
tcp_listen_options.linger.on = true
tcp_listen_options.linger.timeout = 0
tcp_listen_options.sndbuf = 32768
tcp_listen_options.recbuf = 32768
在经典的配置格式中:
[
{rabbit, [
{tcp_listen_options, [
{backlog, 128},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false},
{sndbuf, 32768},
{recbuf, 32768}
]}
]}
].
MQTT和STOMP连接的相同示例:
[
{rabbitmq_mqtt, [
{tcp_listen_options, [
{backlog, 128},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false},
{sndbuf, 32768},
{recbuf, 32768}
]}
]},
{rabbitmq_stomp, [
{tcp_listen_options, [
{backlog, 128},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false},
{sndbuf, 32768},
{recbuf, 32768}
]}
]}
].
请注意,降低TCP缓冲区大小将导致吞吐量成比例下降,因此需要为每个工作负载找到吞吐量和每个连接RAM使用之间的最佳值。将发送和接收缓冲区大小设置为不同的值是危险的,不建议这样做。不建议低于8 KiB的值。
限制连接上的通道数
频道也消耗RAM。通过优化应用程序使用的通道数量,可以减少该数量。可以使用channel_max配置设置限制连接上的最大通道数:
channel_max = 16
请注意,构建在RabbitMQ客户端之上的某些库和工具可能隐含地需要一定数量的通道。很少需要200以上的值。找到最佳值通常是试错的问题。
Nagle的算法(“nodelay”)
禁用Nagle算法主要用于减少延迟,但也可以提高吞吐量。kernel.inet_default_connect_options 和kernel.inet_default_listen_options必须包含{nodelay,true}以禁用Nagle的节点间连接算法。配置为客户端连接提供服务的套接字时, rabbit.tcp_listen_options必须包含相同的选项。这是默认值。以下示例演示了:在rabbitmq.conf中
tcp_listen_options.backlog = 4096
tcp_listen_options.nodelay = true
与高级配置文件中的以下位一起:
[
{kernel, [
{inet_default_connect_options, [{nodelay, true}]},
{inet_default_listen_options, [{nodelay, true}]}
]}].
使用经典配置格式时,所有内容都配置在一个文件中:
[
{kernel, [
{inet_default_connect_options, [{nodelay, true}]},
{inet_default_listen_options, [{nodelay, true}]}
]},
{rabbit, [
{tcp_listen_options, [
{backlog, 4096},
{nodelay, true},
{linger, {true,0}},
{exit_on_close, false}
]}
]}
].
Erlang VM I / O线程池调整
调整大量并发连接时,充足的Erlang VM I / O线程池大小也很重要。请参阅上面的部分。
连接积压
由于客户端数量较少,新连接速率分布非常不均匀,但也足够小,不会产生太大差异。当数量达到数万或更多时,确保服务器可以接受入站连接非常重要。未接受的TCP连接被放入具有有限长度的队列中。此长度必须足以考虑峰值负载小时数和可能的峰值,例如,当许多客户端由于网络中断而断开连接或选择重新连接时。这是使用rabbit.tcp_listen_options.backlog 选项配置的:
tcp_listen_options.backlog = 4096
tcp_listen_options.nodelay = true
在经典的配置格式中:
[
{rabbit, [
{tcp_listen_options, [
{backlog, 4096},
{nodelay, true},
{linger, {true, 0}},
{exit_on_close, false}
]}
]}
].
默认值为128.当挂起的连接队列长度超过此值时,操作系统将拒绝连接。另请参阅 内核调整部分中的net.core.somaxconn。
处理高连接流失
为什么高连接流失是一个问题?
具有高连接流失的工作负载(打开和关闭高连接速率)将需要TCP设置调整以避免某些资源耗尽:最大文件句柄数,RabbitMQ节点上的Erlang进程,内核的临时端口范围(对于*打开的主机) *许多连接,包括联盟链接和铲子连接)等。耗尽这些资源的节点将无法接受新连接,这将对整体系统可用性产生负面影响。
由于某些TCP功能和大多数现代Linux发行版的默认值的组合,可以在较长时间后检测到已关闭的连接。这包含在心跳指南中。这可能是连接建立的一个促成因素。另一个是TIME_WAIT TCP连接状态。该状态主要用于确保来自已关闭连接的重新传输的段不会“重新出现”在具有相同客户端主机和端口的不同(较新)连接上。根据操作系统和TCP堆栈配置,连接可能会在此状态下花费几分钟,这在繁忙的系统上会保证会导致连接建立。有关详细信息,请参阅使用繁忙服务器上的TCP TIME_WAIT连接进行处理。
TCP堆栈配置可以减少关闭状态下的峰值连接数并避免资源耗尽,从而允许节点始终接受新连接。
高连接流失也可能意味着开发人员错误或关于如何使用RabbitMQ支持的消息传递协议的错误假设。所有支持的协议都假设长期连接。打开并几乎立即关闭连接的应用程序不必要地浪费资源(网络带宽,CPU,RAM)并导致本节中描述的问题。
检查连接并收集证据
如果节点未能接受连接,则首先收集数据(度量,证据)以确定系统状态和限制因素(耗尽资源)是很重要的。诸如netstat, ss,lsof之类的工具可用于检查节点的TCP连接。有关示例, 请参阅网络疑难
虽然心跳足以检测失效的连接,但它们在高连接流失情况下还不够。在这些情况下,心跳应与TCP keepalive结合使用,以加快断开连接的客户端检测。
减少TIME_WAIT花费的时间
TCP堆栈调整还可以减少连接在TIME_WAIT状态下花费的时间。该net.ipv4.tcp_fin_timeout设置专门帮助在这里:
net.ipv4.tcp_fin_timeout = 30
请注意,与其他以net.ipv4为前缀的设置一样。,尽管有这个名字,但这个适用于IPv4和IPv6连接。
如果入站连接(来自客户端,插件,CLI工具等)不依赖于NAT,则 net.ipv4.tcp_tw_reuse可以设置为1(启用),以允许内核重用TIME_WAIT状态的套接字以进行传出连接。此设置可应用于客户端主机或中介,例如代理和负载平衡器。请注意,如果使用NAT,则设置不安全,并且可能导致难以追踪问题。
上述设置通常应与减少的TCP keepalive 值结合使用,例如:
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time=30
net.ipv4.tcp_keepalive_intvl=10
net.ipv4.tcp_keepalive_probes=4
net.ipv4.tcp_tw_reuse = 1
操作系统级别调整
操作系统设置可能会影响RabbitMQ的操作。有些与网络直接相关(例如TCP设置),有些则影响TCP套接字以及其他内容(例如打开文件句柄限制)。了解这些限制很重要,因为它们可能会根据工作负载而变化。
一些重要的可配置内核选项包括(请注意,尽管选项名称对IPv4和IPv6连接都有效):
fs.file-MAX
内核将分配的最大文件数。可以使用/ proc / sys / fs / file-nr检查限制和当前值。
net.ipv4.ip_local_port_range
本地IP端口范围,定义为一对值。该范围必须为峰值并发连接数提供足够的条目。
net.ipv4.tcp_tw_reuse
启用后,允许内核在 安全的情况下重用TIME_WAIT状态的套接字。请参阅处理高连接流失。当客户端和对等端使用NAT连接时,此选项很危险。
net.ipv4.tcp_fin_timeout
将此超时降低到15-30秒范围内的值会减少关闭连接将保持TIME_WAIT状态的时间。请参阅处理高连接流失。
net.core.somaxconn
侦听队列的大小(在同一时间建立的连接中有多少个连接)。默认值为128.增加到4096或更高以支持入站连接突发,例如当客户端重新连接时。
net.ipv4.tcp_max_syn_backlog
尚未从连接客户端收到确认的最大记忆连接请求数。默认值为128,最大值为65535.优化吞吐量时,建议使用4096和8192作为起始值。
net.ipv4.tcp_keepalive_ *
net.ipv4.tcp_keepalive_time,net.ipv4.tcp_keepalive_intvl和net.ipv4.tcp_keepalive_probes配置TCP keepalive。AMQP 0-9-1和STOMP具有部分撤消其效果的心跳,即可能需要几分钟来检测无响应的对等体,例如在硬件或电源故障的情况下。MQTT也有自己的keepalives机制,这个机制在不同的名称下是相同的。使用默认设置启用TCP keepalive时,建议将心跳超时设置为8-20秒。另请参阅本指南后面有关TCP keepalives的说明。
net.ipv4.conf.default.rp_filter
启用反向路径过滤。如果 您的系统不关心IP地址欺骗,请将其禁用。
请注意,这些默认值因Linux内核版本和发行版而异。建议使用最新的内核(3.9或更高版本)。
内核参数调整因操作系统而异。本指南重点介绍Linux。要以交互方式配置内核参数,请使用sysctl -w(需要超级用户权限),例如:
sysctl -w fs.file-max 200000
要使更改成为永久更改(坚持重新启动),需要将它们添加到 /etc/sysctl.conf中。有关 更多详细信息,请参阅sysctl(8) 和sysctl.conf(5)。
TCP堆栈调优是一个广泛的主题,在其他地方有很多细节:
TCP套接字选项
常见选项
tcp_listen_options.nodelay
设置为true时,禁用 Nagle的算法。默认为true。强烈建议大多数用户使用。
tcp_listen_options.sndbuf
请参阅本指南前面的TCP缓冲区讨论。默认值由OS自动调整,通常在现代Linux版本的88 KiB到128 KiB范围内。增加缓冲区大小可提高每个连接的使用者吞吐量和RAM使用率 减少会产生相反的效果。
tcp_listen_options.recbuf
请参阅本指南前面的TCP缓冲区讨论。默认值效果类似于rabbit.tcp_listen_options.sndbuf,但对于发布者和协议操作一般。
tcp_listen_options.backlog
未接受的TCP连接队列的最大大小。达到此大小时,将拒绝新连接。对于具有数千个并发连接和可能的批量客户端重新连接的环境,设置为4096或更高。
tcp_listen_options.keepalive
设置为true时,启用TCP keepalive(参见上文)。默认值为false。对于连接可以长时间闲置(至少10分钟)的环境有意义,尽管仍然建议使用心跳超过此选项。
默认
以下是RabbitMQ使用的默认TCP套接字选项配置:
- TCP连接积压限制为128个连接
- Nagle的算法被禁用
- 启用服务器套接字延迟,超时为0
心跳
RabbitMQ支持的一些协议,包括AMQP 0-9-1,支持心跳,一种更快地检测死TCP对等的方法。 有关更多信息,请参阅心跳指南。
net tick time
心跳用于检测客户端和RabbitMQ节点之间的对等或连接故障。net_ticktime用于相同的目的,但用于群集节点通信。低于5(秒)的值可能导致误报,不建议使用。
TCP Keepalive
TCP包含一种类似于心跳(也称为keepalive)的机制,其中包括消息传递协议和上面提到的网络节拍超时:TCP keepalive。由于默认设置不足,TCP keepalive通常不会按照预期的方式工作:检测死对等体需要很长时间(比如一小时或更长时间)。但是,通过调整,它们可以起到与心跳相同的作用,并清理过时的TCP连接,例如,有意或无意地选择不使用心跳的客户端。下面是TCP keepalive的示例sysctl配置,它认为70秒后TCP连接已死或无法访问(连接空闲30秒后每10秒尝试4次):
net.ipv4.tcp_keepalive_time=30
net.ipv4.tcp_keepalive_intvl=10
net.ipv4.tcp_keepalive_probes=4
在RabbitMQ操作员无法控制应用程序设置或使用的客户端库的环境中,TCP keepalive可能是一种有用的附加防御机制。
连接握手超时
RabbitMQ具有连接握手超时,默认为10秒。当客户端在严格受限的环境中运行时,可能需要增加超时。这可以通过rabbit.handshake_timeout(以毫秒为单位)来完成:
handshake_timeout = 20000
使用经典配置格式:
[
{rabbit, [
%% 20 seconds
{handshake_timeout, 20000}
]}
].
应该指出的是,只有非常有限的客户端和网络才需要这样做。其他情况下的握手超时表明其他地方存在问题。
TLS(SSL)握手
如果启用了TLS / SSL,则可能还需要增加TLS / SSL握手超时。这可以通过rabbit.ssl_handshake_timeout(以毫秒为单位)来完成:
ssl_handshake_timeout = 10000
使用经典配置格式:
[
{rabbit, [
%% 10 seconds
{ssl_handshake_timeout, 10000}
]}
].
主机名解析和DNS
在许多情况下,RabbitMQ依赖于Erlang运行时进行节点间通信(包括诸如rabbitmqctl,rabbitmq-plugins等工具)。连接到RabbitMQ节点时,客户端库还执行主机名解析。本节简要介绍与此相关的大多数常见问题。
由客户端库执行
如果客户端库配置为连接到主机名,则会执行主机名解析。根据DNS和本地解析程序(/ etc / hosts和类似的)配置,这可能需要一些时间。不正确的配置可能会导致解决超时,例如在尝试通过DNS 解析本地主机名(如my-dev-machine)时。因此,客户端连接可能需要很长时间(从几十秒到几分钟)。
短和完全限定的RabbitMQ节点名称
RabbitMQ依赖于Erlang运行时进行节点间通信。Erlang节点包括主机名,短(rmq1)或完全限定(rmq1.dev.megacorp.local)。运行时不允许混合使用短名称和完全限定的主机名。群集中的每个节点都必须能够解析每个其他节点的主机名,短或完全限定。默认情况下,RabbitMQ将使用短主机名。设置 RABBITMQ_USE_LONGNAME环境变量以使RabbitMQ节点使用完全限定名称,例如rmq1.dev.megacorp.local。
反向DNS查找
如果rabbit.reverse_dns_lookups配置选项设置为true,则RabbitMQ将对客户端IP地址执行反向DNS查找,并在连接信息中列出主机名(例如,在管理UI中)。
连接事件记录
请参阅日志记录指南中的连接生命周期事件。
网络连接故障排除
网络相关问题的故障排除 方法 在单独的指南中介绍。