RabbitMQ二进制内存消耗

时间:2017-06-08 11:54:44

标签: rabbitmq ubuntu-14.04

根据下面的图片(Rabbit 3.6.6-1)我想知道“二进制文件”在“二进制引用”/故障

上没有显示相同的内存使用情况时所用的内存在哪里

任何人都可以开导吗? 我怀疑某些东西需要“清理”......但是什么?

“二进制”的大量消耗也可以在具有4个队列且没有消息的机器上看到......

编辑2017年7月17日: 我们发现这主要是因为我们打开和关闭了与rabbitmq的多个连接,这在某种程度上似乎没有以干净的方式释放内存。

Rabbit memory consumption Rabbit memory consumption Rabbit memory consumption

1 个答案:

答案 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,这意味着如果客户端死亡而没有机会正常关闭它们,他们就会在那里浪费资源。

有两种方法可以避免此问题:

TCP 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作为后备(即使有更高的超时)也可能是一个好主意。