根据下面的图片(Rabbit 3.6.6-1)我想知道“二进制文件”在“二进制引用”/故障
上没有显示相同的内存使用情况时所用的内存在哪里任何人都可以开导吗? 我怀疑某些东西需要“清理”......但是什么?
“二进制”的大量消耗也可以在具有4个队列且没有消息的机器上看到......
编辑2017年7月17日: 我们发现这主要是因为我们打开和关闭了与rabbitmq的多个连接,这在某种程度上似乎没有以干净的方式释放内存。
答案 0 :(得分:0)
使用内存的最大部分与任何特定消息("二进制引用"屏幕截图的一部分)无关,这表明操作系统资源正在使用此内存由RabbitMQ直接管理。我最大的疑问是开放式连接。
要测试此理论,您可以运行netstat
并查看是否得到类似的结果(假设您在默认端口上运行rabbitmq - 5672):
root@rabbitmqhost:~# netstat -ntpo | grep -E ':5672\>'
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Timer
tcp6 0 0 xxx.xxx.xxx.xxx:5672 yyy.yyy.yyy.yyy:57656 ESTABLISHED 27872/beam.smp off (0.00/0/0)
tcp6 0 0 xxx.xxx.xxx.xxx:5672 yyy.yyy.yyy.yyy:49962 ESTABLISHED 27872/beam.smp off (0.00/0/0)
tcp6 0 0 xxx.xxx.xxx.xxx:5672 yyy.yyy.yyy.yyy:56546 ESTABLISHED 27872/beam.smp off (0.00/0/0)
tcp6 0 0 xxx.xxx.xxx.xxx:5672 yyy.yyy.yyy.yyy:50726 ESTABLISHED 27872/beam.smp off (0.00/0/0)
⋮
有趣的部分是显示"定时器关闭"的最后一栏。这表明这种联系并不是使用Keepalive,这意味着如果客户端死亡而没有机会正常关闭它们,他们就会在那里浪费资源。
有两种方法可以避免此问题:
这些由内核处理。每当连接在一段时间内看不到包时,内核会尝试发送一些探测器以查看对方是否还在那里。 由于当前的Linux(例如4.12)超时默认值非常高(7200秒+每75秒9次探测> 2小时),rabbitmq does not use them by default。
要激活它们,您必须将其添加到rabbitmq.config
:
[
{rabbit, [
⋮
{tcp_listen_options,
[
⋮
{keepalive, true},
⋮
]
},
⋮
]},
⋮
].
并且可能会将超时时间降低到一些更合理的值。这样的事情可能有效(但当然是YMMV):
root@rabbitmqhost:~# sysctl net.ipv4.tcp_keepalive_intvl=30
root@rabbitmqhost:~# sysctl net.ipv4.tcp_keepalive_probes=3
root@rabbitmqhost:~# sysctl net.ipv4.tcp_keepalive_time=60
这些由实际的消息传递协议(例如AMQP,STOMP,MQTT)处理,但要求客户端选择加入。由于每个协议都不同,您必须检查documentation以在客户端应用程序中进行设置。
从避免悬空资源的角度来看,最安全的选择是TCP keepalive,因为您不必依赖于客户端应用程序的行为。 然而,它们的通用性较差,并且如果在高吞吐量时配置错误,而且会突然出现问题。系统可能会导致性能下降,因为误报会导致重新连接。
如果你需要在保持系统性能的同时避免这个问题,那么应用程序协议audbeats是更细粒度的选项,但它们需要更多的协调,因为客户必须选择并选择他们自己的明智的超时。 因为你永远无法100%确定你的客户在没有优雅地关闭连接的情况下会死亡,因此启用TCP keepalive作为后备(即使有更高的超时)也可能是一个好主意。