1 -- 問題現象描述
程式架構背景:
n個業務線程。接收從網路線程傳遞過來的請求,按商務邏輯處理,最後將處理結果形成bytes回傳給網路線程,讓網路將處理結果按原路返回。
1個網路線程。網路線程負責listen、accept、send、recv等底層網路操作。該線程判斷fd上是否有完整的請求,如果已經完整,直接傳遞給業務線程處理。
問題現象描述:
1.業務沒有接到任何請求;
2.參看網路線程的/proc/fd目錄,使用命令 “l -l | wc -l”,發現檔案描述符達到20480個,且一直沒有變動;
3.使用“strace -p 網路線程PID”命令,發現如下問題:
accept(8, 0x7ffff42743f0, [16]) = -1 EMFILE (Too many open files)accept(8, 0x7ffff42743f0, [16]) = -1 EMFILE (Too many open files)accept(8, 0x7ffff42743f0, [16]) = -1 EMFILE (Too many open files)accept(8, 0x7ffff42743f0, [16]) = -1 EMFILE (Too many open files)accept(8, 0x7ffff42743f0, [16]) = -1 EMFILE (Too many open files)accept(8, 0x7ffff42743f0, [16]) = -1 EMFILE (Too many open files)
據此可判斷,server目前維持的連結已經超過進程資源限制。
2 -- 查看運行中進程資源限制
Linux伺服器預設的檔案描述符是1024個,查看方式是執行ulimit -n命令。
對於大規模網路伺服器來說,1024個檔案描述符,意味著最大可接受1024個用戶端,顯然是不夠的。背景程式員需要適當增大該值,具體方法請參考部落格中的其他文章。
在尋找問題的時候,我們可能想知道當前進程被允許的最大檔案描述符個數,或者驗證修改最大檔案描述符後是否已經生效。我們採用如下的辦法:
cat /proc/PID/limits | grep “Max open files”
在實際環境中運行,得結果如下:
motadou@96.108:/home/motadou> cat /proc/22706/limits | grep "Max open files"Limit Soft Limit Hard Limit Units Max open files 204800 204800 files
由此得知,PID為22706的進程最多可以開啟204800個檔案。
3 -- 對“/proc/PID/limits”的分析
motadou@96.108:/home/motadou> cat /proc/22706/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 419430400 419430400 bytes Max resident set 7011418112 unlimited bytes Max processes 62929 62929 processes Max open files 204800 204800 files Max locked memory 65536 262144 bytes Max address space 8322990080 unlimited bytes Max file locks unlimited unlimited locks Max pending signals 62929 62929 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us