線上服務502問題排查---Linux OOM Killer導致的進程消失現象

線上服務502問題排查

問題背景

線上運營平臺有兩臺2C4G的機器組成了集羣,其中服務器A上同時還部署了PDF打印等服務,很明顯4G內存吃緊,一直擔心服務會出現問題,不過運行小半年時間也沒遇到,就不再關心此事了。
有天值班時,運營人員反饋:運營平臺抽風了,時好時壞,嚴重影響了他們的工作。
這事兒可不小,得趕緊排查修復啊!

排查過程

  1. 首先在自己的電腦上訪問運營平臺,正常,未復現,此時13:02了;
  2. 呼朋喚友,同事們也各自訪問運營平臺,5人中,只有老大的電腦訪問時,頁面顯示502;
  3. 於是猜測線上兩臺機器中有一臺出現了問題(具體問題還未知),Nginx沒有將該機器剔除路由列表,有些ip的請求被路由到該機器上了;
  4. 分別查看兩天機器的日誌查看是什麼問題導致請求失敗,發現機器A的日誌停留在12:00,其中沒有任何相關的錯誤信息;
  5. ps -ef|grep xxx命令查看項目進程,發現進程已經消失;

解決方案

  1. 重啓進程,恢復服務;
  2. 編寫檢測腳本,自動檢測項目進程,如果進程消失則自動重啓。

覆盤總結

  1. 線上服務進程爲什麼會莫名其妙地消失?(見下方知識盤點)
  2. 反向代理服務器配置心跳檢測(或健康檢查)機制,自動剔除路由表中的非正常機器。

知識盤點

  1. Linux 內核有個機制叫OOM killer(Out-Of-Memory killer),該機制會監控那些佔用內存過大,尤其是瞬間很快消耗大量內存的進程,爲了防止內存耗盡而內核會把該進程殺掉;
  2. OOM(out-of-memory) killer是通過/proc/$PID/oom_score這個值來決定哪個進程被幹掉的。這個值是系統綜合進程的內存消耗量、CPU時間(utime + stime)、存活時間(uptime - start time)和oom_adj計算出的,消耗內存越多分越高,存活時間越長分越低;總的策略是:損失最少的工作,釋放最大的內存同時不傷及無辜的用了很大內存的進程,並且殺掉的進程數儘量少;
  3. 查看Linux系統的Java進程相關的信息,執行dmesg | grep java命令:

    說明Java進程27372由於得分最高,被OOM_Killer機制給殺掉了;
  4. sudo less /var/log/messages | grep oom-killer命令查看更多相關信息;
  5. 防止重要的進程被Linux殺掉:
  • 保護某個進程不被內核殺掉可以這樣操作:echo -17 > /proc/$PID/oom_adj,其中-17表示禁止killer;
  • 通過修改內核參數禁止OOM機制:vm.panic_on_oom = 1

參考:

  1. 消失的Java進程-Linux OOM Killer
  2. Linux – 內存控制之oom killer機制及代碼分析
  3. Out of memory: Kill process 問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章