最近有台服务器的MQ应用占用内存比较偏高,如下:
      
    
但是看控制台本身内存中消息积压并不多,
      
    
查看rabbtmqctl发现,binary data和other data占据了绝大部分的内存,如下:
     {memory,
     
     [{total,124441400},
     
     {connection_readers,5548680},
     
     {connection_writers,605560},
     
     {connection_channels,2798608},
     
     {connection_other,7775480},
     
     {queue_procs,23561696},
     
     {queue_slave_procs,0},
     
     {plugins,489128},
     
     {other_proc,14147408},
     
     {mnesia,2040288},
     
     {mgmt_db,9741144},
     
     {msg_index,1946696},
     
     {other_ets,2006528},
     
     
      {binary,420491264},
     
     
     {code,20160575},
     
     {atom,711569},
     
     {other_system,
     
      323416776
     
     }]},
    
binary(Memory used by shared binary data in the Erlang VM. In-memory message bodies show up here.)代表的是内存中的消息以及其他一些被queue或者exchange引用的元数据,但是在控制台里面有没有任何体现。
other_system:
Other memory used by Erlang. One contributor to this value is the number of available file descriptors。
看mq日志,发现服务器负载高导致响应慢或者OOM被killed之后,虽然进程本身还在,但收不到有些客户端的心跳,类似如下:
      Missed heartbeats from client, timeout: 10s
      
      Missed heartbeats from client, timeout: 10s
      
      Missed heartbeats from client, timeout: 10s
      
      Missed heartbeats from client, timeout: 10s
      
      Missed heartbeats from client, timeout: 10s
     
跟应用的原开发者确认了下,有些客户端在异常后会不断的尝试重新连接MQ服务器,但是连接都建立了,但是随后心跳就异常了。
照理来说,MQ强制断开客户端连接后,相关的socket和内存占用会随之释放,但是出现异常的时候内存占用一直都很高、而且一两个小时后也没有下降到正常水平。
重启两个java应用后,MQ内存占用就立刻下来了,但是连接数和消费者数量和原来都一样。
这现象似乎和我们原来mysql出现的异常一样,服务端在某些地方可能存在非最常用特性被极为频繁的使用后,可能导致内存存在泄露的情况。
因为之前出现过两三次行情初始化和成交回报丢失的情况,所以趁着这次测试环境的异常大概找到了出现问题的规律,后续会在深入研究下rabbitMQ的binary和other_system里面到底是什么数据,这就又涉及到要分析erlang VM的内存dump才能精确确定了。
 
