open /dev/null: too many open files問題解決

昨晚收到服務器報警郵件,提示如下:

open /dev/null: too many open files

顯然是服務器中打開的文件數太多,準確地說是某個進程打開的文件數太多。那麼,我們先看下進程能夠佔用的最大文件描述符數是多少。

[root@i data0]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 95000
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 95000
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

由輸出結果中的指標open files可知,當前系統一個進程能夠打開的最大文件數是1024。顯然可以增大這個值,有兩種方法,一是直接執行命令:

ulimit -n 16384

但這種方式起的作用是臨時的,如果想永久的生效,則需要修改配置文件limits.conf文件,在其末尾加上如下兩行:

* soft nofile 16384
* hard nofile 16384

然後註銷重啓就可以了。這裏順帶說下limits.conf文件的原理。limits.conf是pam_limits.so的配置文件,/etc/pam.d/下的應用程序調用pam_***.so模塊。當用戶訪問服務器,服務程序將請求發送到PAM模塊,PAM模塊根據服務名稱在/etc/pam.d 目錄下選擇一個對應的服務文件,然後根據服務文件的內容選擇具體的PAM模塊進行處理。

例:限制admin用戶登錄到sshd的服務不能超過2個 在/etc/pam.d/sshd 中添加 session required pam_limits.so;在/etc/security/limits.conf中添加 admin - maxlogins 2

其實還可以看看是哪個進程佔用的文件描述符數超了,這裏就要用到lsof命令了。

[root@localhost data0]# lsof | more
COMMAND     PID      USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
init          1      root  cwd       DIR                8,3      4096          2 /
init          1      root  rtd       DIR                8,3      4096          2 /
init          1      root  txt       REG                8,3    150352      81983 /sbin/init
init          1      root  mem       REG                8,3     65928     114718 /lib64/libnss_files-2.12.so
init          1      root  mem       REG                8,3   1922152     115146 /lib64/libc-2.12.so
init          1      root  mem       REG                8,3     93224     115162 /lib64/libgcc_s-4.4.7-20120601.so.1
init          1      root  mem       REG                8,3     47064     115149 /lib64/librt-2.12.so
init          1      root  mem       REG                8,3    145720     115148 /lib64/libpthread-2.12.so
init          1      root  mem       REG                8,3    268232     115150 /lib64/libdbus-1.so.3.4.0
init          1      root  mem       REG                8,3     39896     114918 /lib64/libnih-dbus.so.1.0.0
init          1      root  mem       REG                8,3    101920     114920 /lib64/libnih.so.1.0.0
init          1      root  mem       REG                8,3    156872     115145 /lib64/ld-2.12.so
init          1      root    0u      CHR                1,3       0t0       3842 /dev/null
init          1      root    1u      CHR                1,3       0t0       3842 /dev/null
init          1      root    2u      CHR                1,3       0t0       3842 /dev/null
init          1      root    3r     FIFO                0,8       0t0       7312 pipe

這裏列出的就是所有打開的文件數,第二列是每個打開的文件對應的進程id。另外這裏顯示的也只是一小部分,實際上還有很多。這時可以執行以下命令查看每個進程對應的打開的文件數。

[root@localhost data0]# lsof | awk '{print $2}' | uniq -c | sort -rn | head -n 10
     89 24833
     77 23132
     73 31469
     70 9557
     69 26242
     68 8893
     68 8643
     68 8626
     68 26210
     68 13002

結果中顯示的第二列是進程id,第一列是該進程打開的文件數,可見pid爲24833的進程打開的文件數最多,並按從多到少排列。知道pid後,就可以通過ps -ef | grep pid查看對應的進程,之後要殺要剮悉聽尊便。

 

 

 

參考文獻:http://alimy.me/post/dev_201601121531/

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