问题现象:
linux服务器上的datamanager后端服务、reportmanager后端服务运行两三天之后就异常停止了。
问题原因排查:
1、排查后端服务的启动日志和log日志,没有任何异常信息记录,确认异常停止原因不是后端服务自身导致;
2、排查linux系统的history操作日志,确认不是由其他同事停止了后端服务;
3、通过
dmesg |grep java命令,确认后端服务是因Out of memory被系统强制kill掉。
下面是命令执行结果:
[root@zcdq-bi backend]# ps -ef | grep java
root
63367
1
0 Jul26 ?
01:39:06
java -ea -Xdebug -XX:+PrintGCDetails -Xmx2048m -jar
trace-log-1.1.0_alpha.jar
root8638884981
2 14:49 pts/1
00:01:21 java
-jar reportManager-0.0.1-SNAPSHOT2019-07-11.jar
root
89654
84981 99 15:39 pts/1
00:00:24 java
-jar dataManager-0.0.1-SNAPSHOT2019-08-08.jar
root
89697
87127 0 15:39 pts/0
00:00:00 grep
--color=auto java
[root@zcdq-bi backend]# ^C
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]# dmesg |grep java
[23497833.885078] [63367]
0
63367 1709633
145030
442
0
0
java
[23497833.885080] [65939]
0
65939 2517459
437717
1005
0
0
java
[23497833.885093] [86388]
0
86388 2506880
389954
938
0
0
java
[23497833.885095] Out of memory: Kill process 65939 ( score
104 or sacrifice child
[23497833.885311] Killed process 65939 ( total-vm:10069836kB,
anon-rss:1750868kB, file-rss:0kB
[23498248.708062] java invoked oom-killer: gfp_mask=0x280da,
order=0, oom_score_adj=0
[23498248.708068] java cpuset=/ mems_allowed=0
[23498248.708071] CPU: 7 PID: 86898 Comm: java Tainted: G
L
------------
3.10.0-327.el7.x86_64
#1
[23498248.708332] [63367]
0
63367 1709633
145030
442
0
0
java
[23498248.708351] [86388]
0
86388 2509191
393861
950
0
0
java
[23498248.708353] [86882]
0
86882 2257267
433281
986
0
0
java
[23498248.708356] Out of memory: Kill process 86882 ( score
103 or sacrifice child
[23498248.708604] Killed process 86882 ( total-vm:9029068kB,
anon-rss:1733124kB, file-rss:0kB
[23500812.639653] [63367]
0
63367 1709633
145031
442
0
0
java
[23500812.639670] [86388]
0
86388 2509703
419759
954
0
0
java
[23500812.639706] [89654]
0
89654 1952866
404281
916
0
0
java
[23500812.639711] Out of memory: Kill process 86388 ( score
100 or sacrifice child
[23500812.639965] Killed process 86388 ( total-vm:10038812kB, anon-rss:1679036kB, file-rss:0kB
-- 系统最新一次强制kill的进程
后端服务Out of memory原因:
首先查看系统内存使用情况,发现可用内存只有1569M,其中有10G的buff和cache,在这种情况下启动两个后端服务,会将可用内存减少到700M,此时会触发Linux内核的OOM killer(Out-of-Memory killer)机制,该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽,内核会把该进程杀掉(通过
dmesg |grep java命令确认)。
[root@zcdq-bi backend]# free -m
total
used
free
shared
buff/cache
available
Mem:
15868
4430
993
7934
10444
1569
Swap:
0
0
0
问题解决方案:
Step1:清除系统的buff和cache
仅清除页面缓存(PageCache)
shell命令:
sync; echo 1 >
/proc/sys/vm/drop_caches
清除目录项和inode
shell命令:
sync; echo 2 >
/proc/sys/vm/drop_caches
清除页面缓存,目录项和inode
shell命令:
sync; echo 3 >
/proc/sys/vm/drop_caches
Step2:后端服务启动限制内存使用
服务启动命令中添加-Xmx512m 参数限制内存使用
nohup java -jar
dataManager-0.0.1-SNAPSHOT2019-08-08.jar -Xmx512m &
Step3:禁止后端服务触发OOM机制
Linux内核会通过特定的算法给每个进程计算一个分数来决定杀哪个进程,每个进程的OOM分数可以在/proc/进程号/oom_score中找到。
可以通过下面这条命令为该进程禁用OOM机制:
echo -17>/proc/进程号/oom_adj
oom_adj的可调值为15到-16,其中15最大,-16最小,-17为禁止使用OOM。
备注:oom_score为2的n此房计算出来的,其中n就是进程的oom_adj值,所以oom_score的分数越高就越会被内核优先杀掉。