坐在安静空荡的办公室,听着楼下打球的声音和汽车的鸣笛声,浮躁的心此时有了片刻的宁静。
最近部署在场外的机器陆续出现ssh远程无法连接的问题,更甚者无法ping通。经过一番调查发现是内存泄露导致,项目的程序随着时间会占用越来越大的内存,当超过系统极限时,操作系统会杀死该进程,如果到此还不会造成其他问题,我们会立刻发现功能无法使用,问题也会就此解决;但是为了确保该程序的运行,在系统的启动脚本里加了检测程序,在检测到程序没有运行的时候会重新运行该程序,这就会导致:泄露→ 被linux杀死 → 重新运行 → 泄露 → 被linux杀死 。。。。。无限循环
#检测脚本
#!/bin/sh
while true;do
ps |grep dx201 |grep -v grep
if [ $? -ne 0 ]
then
./dx201
else
echo "runing....."
fi
sleep 1
done
linux根据OOMKILL机制判断耗尽内存的程序,然后杀死,有时候也会伤及无辜,然后sshd悲催的躺枪了,所以我们发现sshd也连不上了。。
dmesg命令输出内核log可以看到杀死的过程,oom_score_adj是每个程序的分数,分数越高越容易被杀,当然分数的计算操作系统是有自己的算法的。
[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name
[ 1415] 0 1415 439 46 2 -17 -1000 udevd
[ 3119] 0 3119 1011 64 0 0 0 sshd
[ 3156] 0 3156 593 51 2 0 0 sh
[ 3159] 0 3159 561 33 3 0 0 run_thread
[ 3160] 0 3160 561 33 1 0 0 fun_thread
[23339] 0 23339 1651 115 2 0 0 sshd
[23343] 0 23343 595 36 1 0 0 sh
[23494] 0 23494 2588 27 3 0 0 fun_process
[25019] 0 25011 217625 182630 3 0 0 dx201
Out of memory: Kill process 25019 (dx201) score 926 or sacrifice child
内存泄露解决了,后来又出现的系统负载过高的问题,执行uptime可以查看系统运行时间和CPU负载:
root@myzr ~$ uptime
18:35:21 up 22 days, 9:36, 1 users, load average: 2.78, 2.88, 2.93
我们项目机器是4核的,所以4以内都还ok(核数除以负载数就是每个CPU上任务数,越大CPU越繁忙,执行其他程序的机会越少),读者可以跑四个没有sleep的while循环程序试试,负载飞速涨,几十分钟后你就会发现网络崩了。。
内核log频繁的打印也会导致系统异常,如果你系统中有频繁打印系统log的程序(一般linux默认只打印异常的系统log),执行dmesg -n 8(打印所有内核log),你就会发现系统越来越卡顿。。一段时间以后系统崩溃。