線上應用遇到了oom killer

概述


在2019年10月21日,公司的一個後臺應用中【生成營銷活動數據】的操作,執行到一半突然不執行了,導致部分活動數據沒生成,運營人員對此怨聲載道的,因爲影響了他們的運營效率了,要求我們技術人員儘快解決。


機器內存配置


用的是騰訊雲,內存配置是8G


定位過程


首先是從日誌入手,grep一下,發現線程執行到某一行代碼後,就不往下執行了,因爲:

  • 後續的日誌都沒打印了,而業務操作又還沒完成;
  • 代碼裏也用try catch捕獲所有異常,但是也沒看到異常日誌;

真是活見鬼了,線程不可能憑空消失,當時又從下面兩個方向找了一下:

1、 有沒有可能執行業務代碼的過程中,代碼裏把異常給吞掉了,沒有拋出來,後面一行一行代碼仔細的看,並沒有這樣的代碼;
2、 內存泄漏了,操作系統直接將進程給kill掉了,通過查看/var/log/messages日誌,發現瞭如下信息:

java invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0

看了一下時間點,剛好是線程不打印日誌的時間點。那到底是誰想申請內存的時候,內存不足觸發了這次的oom-killer呢?從上面的信息裏,看到了是JAVA應用本身觸發的。

java invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0

從紅色部分的java字眼就可以看出來。那麼當時這個JAVA進程佔用的實際物理內存是多少呢?可以從messages文件裏看到的。

[ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
[  353]     0   353    33677      169      72        0             0 systemd-journal
[  386]     0   386    31198      102      28        0             0 lvmetad
[  390]     0   390    11089      168      24        0         -1000 systemd-udevd
[  574]     0   574    13877      165      27        0         -1000 auditd
[  593]     0   593     6627      176      18        0             0 systemd-logind
[  594]   998   594   135161     1429      61        0             0 polkitd
[  598]    81   598    15074      233      34        0          -900 dbus-daemon
[  603]     0   603     1096       42       8        0             0 acpid
[  608]   997   608     2144       38      10        0             0 lsmd
[  614]     0   614    31578      242      21        0             0 crond
[  619]     0   619     6476       50      18        0             0 atd
[  836]     0   836   143454     3314      99        0             0 tuned
[  981]     0   981     9433     4597      14        0             0 secu-tcs-agent
[ 1251]     0  1251    27522       41      10        0             0 agetty
[ 1253]     0  1253    27522       41      11        0             0 agetty
[ 4595]     0  4595    24363      187      20        0             0 sgagent
[ 8538]     0  8538    38819     1642      30        0             0 barad_agent
[ 8539]     0  8539    41134     2094      34        0             0 barad_agent
[ 8540]     0  8540   316655     3358      62        0             0 barad_agent
[27410]     0 27410    25579      176      20        0             0 YDLive
[ 2537]     0  2537    28203      279      56        0         -1000 sshd
[ 2583]   995  2583    21282      218      42        0             0 zabbix_agentd
[ 2584]   995  2584    21282      358      42        0             0 zabbix_agentd
[ 2585]   995  2585    21313      333      44        0             0 zabbix_agentd
[ 2586]   995  2586    21313      302      44        0             0 zabbix_agentd
[ 2587]   995  2587    21313      320      44        0             0 zabbix_agentd
[ 2588]   995  2588    21315      287      44        0             0 zabbix_agentd
[ 9679]     0  9679   104952    70374     171        0             0 YDService
[32245]     0 32245  2850134  1825088    4092        0             0 java
[ 2450]     0  2450   222649     6005     265        0             0 rsyslogd
[23801]     0 23801    28293      108      14        0             0 watchdog.sh
[ 2370]     0  2370    26987       52      11        0             0 sleep
[ 2483]     0  2483    32643      292      21        0             0 crond
[ 2484]     0  2484    32643      292      21        0             0 crond
[ 2485]     0  2485    32643      292      21        0             0 crond
[ 2486]     0  2486    32643      292      21        0             0 crond
Out of memory: Kill process 32245 (java) score 886 or sacrifice child
Killed process 32245 (java) total-vm:11400536kB, anon-rss:7300352kB, file-rss:0kB, shmem-rss:0kB

被操作系統kill掉的是java進程是32245,佔用的物理內存是:anon-rss:7300352kB,換算成G的單位:

7300352/(1024*1024)=6.9G

而當時整個應用服務器上,所有進程佔用的總的物理庫存是(將rss列上的值累加起來):

(169+102+168+165+176+1429+233+42+38+242+50+3314+4597+41+41+187+1642+2094+3358+176+279+218+358+333+302+320+287+70374+1825088+6005+108+52+292+292+292+292)4/(10241024)=7.3G

這樣看起來,還有幾百兆的空餘內存,但是還是觸發了oom-killer。谷歌一把,發現確實存在這種情況,但是具體是爲啥,相關的文章講的都不太清楚。暫時搞不懂,有網友知道原因,麻煩告知一下。


解決方案


【生成營銷活動數據】的操作是比較耗內存,且由於歷史數據堆積的越來越多,造成了線程查詢的數據會越來越多,便先將歷史數據歸檔。另外由於該應用是個單體應用,堆積了非常多的功能,只要某個功能耗內存多了,都可能導致oom killer,運營人員又死催爛催的,讓我們感覺解決,因此先將機器的內存配置升級到16G

後面又多次跑了這個批量指派任務,沒觸發oom killer了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章