天天看點

Linux:如何擷取打開檔案和檔案描述符數量

一、linux的檔案描述符

   檔案描述符(FD:file descriptors),也可以說是檔案句柄,當某個程式打開檔案時,核心傳回相應的檔案描述符,程式為了處理該檔案必須引用此描述符。檔案描述符是一個正整數,用以标明每一個被程序所打開的檔案和socket。最前面的三個檔案描述符(0,1,2)分别與标準輸入(stdin),标準輸出(stdout)和标準錯誤(stderr)對應,後面打開的檔案依此類推對應3、4…… 。

    linux系統對每個使用者、程序、或整個系統的可打開檔案描述符數量都有一個限制,一般預設為1024。當我們在系統或應用的日志中碰到“too many open files”錯誤記錄時,這個其實不是說打開的檔案過多,而是打開的檔案描述符數量已達到了限制,這時就需要增加檔案描述符的數量限制了。

1.1 擷取系統打開的檔案描述符數量

    [root@localhost ~]# cat /proc/sys/fs/file-nr 

    1216    0       197787

     //第一列 1216   :為已配置設定的FD數量

     //第二列 0          :為已配置設定但尚未使用的FD數量

     //第三列197787:為系統可用的最大FD數量

    已用FD數量=為已配置設定的FD數量 - 為已配置設定但尚未使用的FD數量。注意,這些數值是系統層面的。

1.2 擷取程序打開的檔案描述符數量

    [root@localhost ~]# pidof vim

      3253

    [root@localhost ~]# ll /proc/3253/fd

     總用量 0

    lrwx------. 1 test test 64  6月  8 18:11 0 -> /dev/pts/0

    lrwx------. 1 test test 64  6月  8 18:11 1 -> /dev/pts/0

    lrwx------. 1 test test 64  6月  8 18:11 2 -> /dev/pts/0

    lrwx------. 1 test test 64  6月  8 18:11 4 -> /home/test/.bash_history.swp

    //可以看到vim程序用了4個FD

1.3 更改檔案描述符限制

    當碰到“too many open files”錯誤時,就需要增加檔案描述符的限制數量,系統的預設檔案描述符都比較大,一般來說,隻需增加使用者或程序的就可以了

    //使用者或程序

    [root@localhost ~]# ulimit -n

     1024

    [root@localhost ~]# ulimit -n 10240

    [root@localhost ~]# ulimit -n

     10240 

注意,使用ulimit 指令更改後隻是在目前會話生效,當退出目前會話重新登入後又會回到預設值1024,要永久更改可以修改檔案 /etc/security/limit.conf,如

   [root@localhost ~]#vi /etc/security/limits.conf 

   加入 “abc hard nofile 10240”

   abc:使用者名,即允許test使用ulimit指令更改FD限制,最大值不超過10240,更改後abc使用者的每一個程序(以abc使用者運作的程序)可打開的FD數量為10240個

   hard:限制類型,有soft/hard兩種,達到soft限制會在系統的日志(一般為/var/log/messages)裡面記錄一條告警日志,但不影響使用。hard,達到這個限制,有日志且會影響使用。

   nofile:限制的内容,nofile - max number of open files

   1024 :值

更改後,退出終端重新登入,用ulimit看看有沒有生效,如果沒生效,可以在abc使用者的.bash_profile檔案加上 ulimit -n 10240 ,以使使用者abc每次登入時都會将FD最大值更改為10240,如:

   [root@localhost ~]#echo "ulimit -n 10240" >> /home/abc/ .bash_profile

    10240

   [root@localhost ~]# su - abc

   [abc@localhost ~]$ ulimit -n

    10240

limit.conf檔案裡面本身已有很詳細的使用方法,這個下次可以說說。

      //系統級别

 将整個作業系統可以使用的FD數量更改為51200

     [root@localhost ~]# echo "51200" > /proc/sys/fs/file-max

     [root@localhost ~]# cat /proc/sys/fs/file-nr

     1184    0       51200

像這樣更改在系統重新開機後會恢複到預設值,要永久更改可以在sysctl.conf檔案加上fs.file-max = 51200

如:

    [root@localhost ~]# echo "fs.file-max = 51200" >> /etc/sysctl.conf

二、擷取打開的檔案數量

linux的一切皆為檔案,那麼如何知道系統/應用打開了哪些或是多少個檔案呢?很簡單,用lsof指令就行了,lsof,list  open files的簡寫,可列出程式或系統正在使用的檔案。

2.1 擷取整個系統打開的檔案數量

     [root@localhost ~]# lsof |wc -l

       1864

2.2 擷取某個使用者打開的檔案數量 

    [root@localhost ~]# lsof -u test |wc -l

       15

2.3 擷取某個程式打開的檔案數量 

   [root@localhost ~]# pidof vim

      3253

    [root@localhost ~]# lsof -p 3253 |wc -l

      31

上面所示隻是用lsof來顯示已打開的檔案數量,lsof的功能遠不止這些,有興趣可以man lsof看一下 

三、程序打開的檔案描述符與檔案

如前面說的,為什麼說“too many open files”錯誤不是說打開的檔案過多,而是打開的檔案描述符數量已達到了限制,這個簡單的可以用man ulimit就可得知

[abc@localhost ~]$   man ulimit 

//找到ulimit,可以看到下列一行

-n   The maximum number of open file descriptors (most systems do not allow this value to be set)

這行就說明了用ulimit -n xxx 更改的是檔案描述符而不是檔案的最大值。

 我們可以來測試一下:

  •  打開一個程序vim,擷取vim打開的檔案及檔案描述符數量

[abc@localhost ~]$ lsof -p 3330 |wc -l //檔案數量

31

[abc@localhost ~]$ ls /proc/3330/fd |wc -l  //檔案描述符數量

4

[abc@localhost ~]$ killall -9 vim

[1]+  已殺死               vim .bash_profile

[abc@localhost ~]$ ulimit -n 20

  • 更改限制,并測試vim的運作情況

[abc@localhost ~]$ ulimit -n 20 //更改為20,即小于檔案數量31

[abc@localhost ~]$ ulimit -n

20

[abc@localhost ~]$ vim .bash_profile //可看到vim可以正常打開檔案

# .bash_profile

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

        . ~/.bashrc

fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH

ulimit -n 10240

----------------------------------

[abc@localhost ~]$ ulimit -n 3    //更改為3,即小于FD數量4

[abc@localhost ~]$ ulimit -n

3

[abc@localhost ~]$ vim .bash_profile   

-bash: start_pipeline: pgrp pipe: Too many open files 

vim: error while loading shared libraries: libselinux.so.1: cannot open shared object file: Error 24

從上面可看到小于檔案描述符的數值時即報“Too many open files”錯誤,那麼這個應該可以說明這個“Too many open files”錯誤是是打開的檔案描述符數量已達到了限制所引起的,跟打開的檔案數量沒有關系。

另用lsof可知道程序都打開了哪些檔案和檔案描述符:

[abc@localhost ~]$ lsof -p 3330

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME

vim     3555  abc  cwd    DIR  253,0     4096 923587 /home/abc

vim     3555  abc  rtd    DIR  253,0     4096      2 /

vim     3555  abc  txt    REG  253,0  1971360 287900 /usr/bin/vim

vim     3555  abc  mem    REG  253,0   155696    846 /lib64/ld-2.12.so

vim     3555  abc  mem    REG  253,0    26104 281208 /usr/lib64/libgpm.so.2.1.0

vim     3555  abc  mem    REG  253,0  1912928    847 /lib64/libc-2.12.so

vim     3555  abc  mem    REG  253,0    22536    852 /lib64/libdl-2.12.so

vim     3555  abc  mem    REG  253,0   145672    859 /lib64/libpthread-2.12.so

vim     3555  abc  mem    REG  253,0   598816    848 /lib64/libm-2.12.so

vim     3555  abc  mem    REG  253,0   124624    857 /lib64/libselinux.so.1

vim     3555  abc  mem    REG  253,0   113904    856 /lib64/libresolv-2.12.so

vim     3555  abc  mem    REG  253,0  1489600 406575 /usr/lib64/perl5/CORE/libperl.so

vim     3555  abc  mem    REG  253,0   142504     96 /lib64/libncurses.so.5.7

vim     3555  abc  mem    REG  253,0    34336    890 /lib64/libacl.so.1.1.0

vim     3555  abc  mem    REG  253,0    43392    869 /lib64/libcrypt-2.12.so

vim     3555  abc  mem    REG  253,0   387880    868 /lib64/libfreebl3.so

vim     3555  abc  mem    REG  253,0  1753952 271694 /usr/lib64/libpython2.6.so.1.0

vim     3555  abc  mem    REG  253,0    17520    886 /lib64/libutil-2.12.so

vim     3555  abc  mem    REG  253,0   138280    826 /lib64/libtinfo.so.5.7

vim     3555  abc  mem    REG  253,0    20280    887 /lib64/libattr.so.1.1.0

vim     3555  abc  mem    REG  253,0   116136    889 /lib64/libnsl-2.12.so

vim     3555  abc  mem    REG  253,0    61624     42 /lib64/libnss_files-2.12.so

vim     3555  abc  mem    REG  253,0    26050 265158 /usr/lib64/gconv/gconv-modules.cache

vim     3555  abc  mem    REG  253,0   124855 528606 /usr/share/vim/vim72/lang/zh_CN/LC_MESSAGES/vim.mo

vim     3555  abc  mem    REG  253,0   135533 528604 /usr/share/vim/vim72/lang/zh_CN.UTF-8/LC_MESSAGES/vim.mo

vim     3555  abc  mem    REG  253,0 99158752 264902 /usr/lib/locale/locale-archive

vim     3555  abc    0u   CHR  136,0      0t0      3 /dev/pts/0

vim     3555  abc    1u   CHR  136,0      0t0      3 /dev/pts/0

vim     3555  abc    2u   CHR  136,0      0t0      3 /dev/pts/0

vim     3555  abc    4u   REG  253,0     4096 923589 /home/abc/.bash_profile.swp

可看到運作vim時,打開了很多個檔案,但檔案描述符隻有後面四個。