早上发现网站无法访问,查看状态码,是502,即知道是负载后端的应用停服。登录服务器,进程确认已经不存在。检查应用日志,却发现并无异常,很奇怪进程为啥会挂掉。
查看 /var/log/message 发现如下信息:
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
......
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15324] 0 15324 38678 328 79 0 0 sshd
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15328] 0 15328 18062 210 39 0 0 sftp-server
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15775] 0 15775 588027 91836 240 0 0 java
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15822] 0 15822 38711 405 81 0 0 sshd
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15879] 0 15879 45594 249 46 0 0 crond
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15881] 0 15881 28296 66 11 0 0 run-parts
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15893] 0 15893 156948 53661 229 0 0 yum-cron
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: [15894] 0 15894 28386 36 12 0 0 awk
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: Out of memory: Kill process 15775 (java) score 352 or sacrifice child
Jun 28 16:08:55 iZ8vbxxx1u3Z kernel: Killed process 15775 (java), UID 0, total-vm:2352108kB, anon-rss:366108kB, file-rss:1236kB, shmem-rss:0kB
看来是触发了Linux内核的“Out Of Memory killer”机制;
当剩余内存空间大小过低时,OOM killer就会选取一个进程强制kill。
被kill进程的选取主要基于2点:
- kill它能释放最多的内存;
- 对系统来说kill它的影响最小。
实际操作上,内核对每个进程都维护了一个 oom_score 值。值越高,越可能被OOM Killer选中。当前基本就是占用内存量。
$ cat /proc/pid/oom_score
如果不想进程被kill,一种方法时修改它的 oom_score_adj 值。设置为 -1000 时,OOM Killer 就会忽略这个进程。
sudo echo -1000 > /proc/pid/oom_score_adj
或者,修改服务Unit
[Service]
OOMScoreAdjust=-1000
当然这两个方式都相当不清爽。
这时,小伙伴提示了一下,ECS内存只有1G。
什么?才配置了1G?。。。确认程序无内存泄漏后,套餐升级成4G。问题解决。