【问题标题】:RabbitMQ Binary memory consumptionRabbitMQ 二进制内存消耗
【发布时间】:2017-08-17 06:36:13
【问题描述】:

根据下面的图片(Rabbit 3.6.6-1)我想知道当“二进制引用”/细分中没有显示相同的内存使用情况时,用于“二进制”的所有内存在哪里

谁能解惑? 我怀疑有些东西需要“清理”...但是什么?

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

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

【问题讨论】:

  • 这里有什么解决办法吗?我们在 3.6.10 中看到了同样的情况。
  • 目前我们只是将其确定为我们的一个 PHP 脚本,但我们仍需要对此进行更多调查......可能是 AMQP 库或类似库

标签: rabbitmq ubuntu-14.04


【解决方案1】:

已用内存的最大部分与任何特定消息(屏幕截图的“二进制引用”部分)无关这一事实表明,该内存正被不由 RabbitMQ 直接管理的操作系统资源使用。我最大的怀疑是开放连接。

要测试这个理论,你可以运行netstat 看看你是否得到类似的结果(假设你在默认端口 - 5672 上运行 rabbitmq):

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)
⋮

有趣的部分是显示“定时器关闭”的最后一列。这表明这个连接没有使用keepalives,这意味着如果客户端死掉而没有机会优雅地关闭它们,它们只会挂在那里吃掉资源。

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

TCP 保活

这些由内核处理。每当一个连接在一定时间内没有看到任何包时,内核就会尝试发送一些探测以查看另一端是否仍然存在。 由于当前的 Linux(例如 4.12)超时默认值非常高(7200 秒 + 每 75 秒 > 2 小时 9 次探测),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,因为您不必依赖客户端应用程序的行为。 但是,它们的通用性较差,如果在高吞吐量但“突发”系统上配置错误,可能会导致性能下降,因为误报会导致重新连接。

如果您需要在保持系统性能的同时避免此问题,则应用程序协议心跳是更细粒度的选项,但它们需要更多的协调,因为客户端必须选择加入并选择自己的合理超时。 由于您永远无法 100% 确保您的客户端在不正常关闭连接的情况下不会死掉,因此启用 TCP keepalives 作为后备(即使超时时间较长)也可能是一个好主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-02
    • 2019-08-17
    • 2022-06-14
    • 2021-03-29
    • 2015-11-30
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多