1. 程式人生 > >Tomcat 程序自動退出問題

Tomcat 程序自動退出問題

最近在專案裡遇到這樣一個問題:

應用部署線上下伺服器上,線下伺服器,相對來說配置低一些,同時可能和其它的服務部署在一起。

後來遇到一個比較怪異的問題:

應用跑一段時間,Tomcat程序就掛掉了。

而且這個沒有什麼規律,不是在特定操作執行時,或者特定時間出現。同時沒有任何的日誌。本來以為是其它的服務的人把我們的不小心kill掉了,但kill的有點太頻繁了,同時和QA同學瞭解到,線上下伺服器上的其他服務,目前都沒有操作過,排除了人為的可能。

剩下的就只能從應用自身的問題入手了。但整個程序掛掉的時候,並沒有任何日誌生成,同時也沒有生成Crash檔案。還嘗試在啟動指令碼中增加

-XX:+HeapDumpOnOutOfMemoryError,想要分析下堆內資料,程序退出時也是什麼都沒生成。

這時就只能請教萬能的網路了,Google之後瞭解到一個Linux OOM Killer。按照這個思路和提供的方式去查看了伺服器的日誌,果然問題在這兒。

Linux OOM Killer

在這裡有一個關於OOM Killer的描述

It is the job of the linux ‘oom killer’ to sacrifice one or more processes in order to free up memory for the system when all else fails. It will also kill any process sharing the same mm_struct as the selected process, for obvious reasons. Any particular process leader may be immunized against the oom killer if the value of its /proc//oomadj is set to the constant OOM_DISABLE (currently defined as -17).

長話短說就是,Linux Kernel的這個Killer,會在記憶體不足的時候kill掉任何 不受保護的程序,從而釋放記憶體,保證Kernel的執行。

要讓自己的程序成為一個受保護的程序,請注意這一句:

Any particular process leader may be immunized against the oom killer if the value of its /proc//oomadj is set to the constant OOM_DISABLE (currently defined as -17 ).

操作方式上可以使用

,寫一個定時任務,執行指令碼,把當前程序的Pid加到這個oomadj裡。

那怎麼判斷程序是不是被OOM Killer給幹掉了呢?

可以從 /var/log/messages 這個檔案裡查詢下,是否有之前pid對應的程序Kill資訊,或者程序名,比如我們這裡說的是Java應用,就直接查Java的就可以,像

這樣的內容,

“Out of memory: Kill process 31201 (java) score 783 or sacrifice child

如果沒有這個檔案的許可權,也可以直接使用如下命令

dmesg| egrep -i ‘killed process’

會有類似這樣的輸出

Killed process 13090 (java)

知道是被OOM Killer幹掉的,那下一步就只能是保證環境的記憶體夠用了,少被其它程式佔用,加到受保護程序裡,或者直接換個記憶體充足的伺服器吧。 ^_^.

最後來看張圖

Reference