RabbitMQ的crash dump文件分析
Contents
原因
今天一早来到公司,同事说客户反馈生产上的系统数据没有进来了。所以,就排查了下问题才行。
最直接的,先看Tomcat的日志,可以发现到:
Dec 01, 2016 11:01:31 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [ROOT] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused] with root cause
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
无语,又是RabbitMQ
连接不上。
分析crash文件
进入到RabbitMQ,看到有个文件在安装目录下:
-rw-r----- 1 xxx xxx 30908860 Dec 1 09:29 erl_crash.dump
然后接下来就是分析这个crash日志文件了。
分析工具:
github recon erl_crashdump_analyzer
分析
直接执行如何命令即可:
./erl_crashdump_analyzer.sh erl_crash.dump
````
### 输出样本
bash analyzing erl_crash.dump-2016-12-1, generated on: Thu Dec 1 09:28:44 2016
Slogan: eheap_alloc: Cannot allocate 169124672 bytes of memory (of type “heap”).
Memory:
processes: 362 Mb processes_used: 362 Mb system: 181 Mb atom: 0 Mb atom_used: 0 Mb binary: 70 Mb code: 18 Mb ets: 83 Mb
total: 544 Mb
Different message queue lengths (5 largest different):
1 1
367 0
Error logger queue length:
0
File descriptors open:
UDP: 0 TCP: 10 Files: 77
Total: 87
Number of processes:
368
Processes Heap+Stack memory sizes (words) used in the VM (5 largest different):
1 24722235
1 7582861
2 2072833
1 1727361
2 833026
Processes OldHeap memory sizes (words) used in the VM (5 largest different):
1 28690
1 10958
1 6772
3 4185
3 2586
Process States when crashing (sum):
1 Garbing
1 Scheduled
366 Waiting
导致RabbitMQ crash的原因就在 `Slogan` 这一行里:比如这里,就是因为 ` Cannot allocate 169124672 bytes of memory (of type "heap").` (在堆上分配不到 169124672 bytes 的内存导致崩溃)
### 内存列说明
bash total:当前分配给进程 processes 和系统 system 的内存总量 processes:当前分配给 Erlang 进程的内存总量 processes_used:当前已被 Erlang 进程使用的内存总量(进程内存的一部分) system:当前分配给 Erlang 虚拟机,不过没有被 Erlang 进程占用的内存总量。 atom:当前分配给原子的内存总量(系统进程的一部分) atom_used:当前已被 原子使用的内存总量(系统进程的一部分) binary:当前分配给二进制数据的内存总量(系统进程的一部分) code:当前代码数据所占用的内存总量(系统进程的一部分) ets:当前分配给 ETS 表的内存总量(系统进程的一部分) ```
参考资料
解决
添加swap分区
发现生产上的系统,根本没有swap分区。如果允许的话,可以添加一个swap分区来进行内存交换到磁盘的缓冲(这个会导致性能下降)
增大内存
因为是使用阿里云,所以,可以动态扩展机器性能
优化程序
尽可能不让MQ堆积太多数据,应该及时处理好出入队的速率