1. 程式人生 > >nginx問題定位之監控程序異常退出

nginx問題定位之監控程序異常退出

nginx在執行過程中是否穩定,是否有異常退出過?這裡總結幾項平時會用到的小技巧。

1. 在error.log中檢視是否有signal項,如果有,看看signal是多少。

比如,這是一個異常退出的情況:

$grep signal error.log

2012/12/24 16:39:56 [alert] 13661#0: worker process 13666 exited on signal 11

如果在程序退出後,有coredump檔案產生,則會打出如下日誌:

$grep signal error.log

2012/12/24 16:39:56 [alert] 13661#0: worker process 13666 exited on signal 11 (core dumped) 

2. 簡單方式,看程序號是否連續

一般來說,在worker程序啟動時,其程序號都是連續的(至少相差不是很遠),如果有程序退出,其程序號就不一定連續。

$ps aux | grep nginx

lizi      7223  0.0  0.0  74844  2024 ?        Ss   13:32   0:00 nginx: master process ./nginx
lizi      7292  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7293  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7294  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7295  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7296  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7297  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7298  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7299  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7300  0.0  0.0  78856  5468 ?        S    13:33   0:00 nginx: worker process
lizi      7301  0.0  0.0  78856  5452 ?        S    13:33   0:00 nginx: worker process

可以看到,10個worker程序,基本從7292到7301,程序號連續。
如下:

$ps aux | grep nginx

nobody    9492 16659 26 09:18 ?        01:10:41 nginx: worker process
root      16659     1  0 Dec24 ?       00:00:00 nginx: master process ./nginx
nobody   16663 16659 11 Dec24 ?        02:41:38 nginx: worker process
nobody   19344 16659 24 10:18 ?        00:50:54 nginx: worker process
nobody    25447 16659 28 07:41 ?        01:43:56 nginx: worker process 

程序號已不再連續,說明nginx可能有工作程序異常退出。

3. 檢視dmesg系統訊息。

在man手冊裡面是這麼描述dmesg的:

DESCRIPTION
dmesg is used to examine or control the kernel ring buffer.

檢視dmesg是檢測系統執行狀態的常用手段,通常可以幫我們排查很多問題。當然,如果有程序異常退出,dmesg也可以看到。

$dmesg

nginx[24721]: segfault at 0000000000000001 rip 0000000000000001 rsp 00007ffff58d8180 error 14
nginx[1729]: segfault at 0000000000000190 rip 00000000004c2d27 rsp 00007ffff58d8340 error 4
nginx[22002]: segfault at ffffffffffffffff rip 000000001c959744 rsp 00007fff43caac18 error 6

rip表示程式退出時的ip暫存器內容,當沒有core檔案可用時,可根據此值以及反彙編來查詢程式core的位置。

4. 開啟coredump檔案。

一般我們在程式啟動前,通過ulimit -c ulimited來設定core檔案的大小,也可以修改/etc/security/limits.conf檔案,新增如下資訊:

admin               soft    core            1000000
admin               hard    core            1000000

也可以直接修改nginx的配置檔案,新增如下配置項:

worker_rlimit_core 10000m;

而此時,在limit系統中,預設coredump檔案會寫在啟動nginx時的目錄,如果nginx在啟動時worker程序的使用者沒有許可權寫到這個目錄,程序在異常退出時,就無法產生coredump檔案。由於nginx啟動後,或者是由別人啟動,我們無法知道nginx在啟動時的目錄,也就無法知道core檔案的目錄。我曾經碰到過這樣的問題,通過日誌檢視,是coredump出來了,但卻找不到coredump的檔案。

這裡有一個小技巧,檢視/proc/pid/cwd可以看到程序的工作目錄,而core檔案會產生在工作目錄。

nginx可以配置工作目錄來改變預設的工作目錄,於是,我們需要配置working_directory為目的工作目錄,我們的core檔案也會產生在這個目錄。

working_directory /path/to/core;

working_directory與編譯時指定的--prefix=/path不同,後者表示在配置檔案中所用的相對路徑所生產的絕對路徑。所以,working_directory不會影響到配置的引用路徑,而僅僅是為了改變core檔案的路徑,當然nginx必須有寫這個目錄的許可權,否則無法core出來。

所以,這裡,我推薦的做法是,配置worker_rlimit_coreworking_directory這兩個指令,這樣,就不需要修改作業系統的引數就可以正常core出來了。

以上這些是平時用到的一些技巧的總結,大家玩得開心!