Linuxオープンファイル数1024制限の原理と解決方法


/proc/sys/fs/file-max 
このファイルは、割り当て可能なファイルハンドルの最大数を指定します.
最大値を表示:
[root@localhost home]# cat /proc/sys/fs/file-max 
100977
[root@localhost home]#

これは、このLinuxシステムが最大100977個のファイルを同時に開くこと(すなわち、すべてのユーザーが開くファイル数の合計を含む)を許可していることを示しています.Linuxシステムレベルのハード制限であり、すべてのユーザーレベルの開くファイル数の制限はこの数値を超えてはいけません.通常、このシステム・レベルのハード・リミットは、Linuxシステムが起動時にシステムのハードウェア・リソースの状況に基づいて計算される最適な最大同時オープン・ファイル数制限です.特に必要がない場合は、ユーザー・レベルのオープン・ファイル数制限にこの制限を超える値を設定しない限り、この制限を変更するべきではありません.このパラメータのデフォルト値はメモリサイズに関係しており、物理メモリを増やした後にマシンを再起動すると、この値が大きくなります.約1 Gメモリ10万個のハンドルの線形関係.
値の変更:
ユーザーが得たエラーメッセージが「too many open files」のように宣言されている場合、開くファイルの数が最大値に達しているため、より多くのファイルを開くことができない場合は、この値を増やす必要がある場合があります.
[root@localhost home]# vim /etc/rc.local 

#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
echo 222158 > /proc/sys/fs/file-max    ;    ,  file-max 
touch /var/lock/subsys/local
[root@localhost home]# reboot
[root@localhost ~]# cat /proc/sys/fs/file-max 
222158
[root@localhost ~]#

このハードリミットを変更する方法は/etc/rcを変更することである.localスクリプト、スクリプトに次のように追加します:echo 22158>/proc/sys/fs/file-maxこれはLinuxが起動完了後にシステムレベルのオープンファイル数のハード制限を22158に強制的に設定することです.変更後、このファイルを保存します.
/proc/sys/fs/file-nr 
このファイルはfile-maxに関連しており、割り当てられたファイルハンドルの数使用済みファイルハンドルの数ファイルハンドルの最大数は読み取り専用で、情報を表示するためにのみ使用されます.
[root@localhost ~]# cat /proc/sys/fs/file-nr 
2112	0	222158
[root@localhost ~]#

システムファイルのオープン数を変更するには、次の手順に従います.
/etc/security/limitsを変更します.confファイル、現在のシステムファイルのオープン数を変更します.limits.confのフォーマットは次のとおりです.
               
:個々のユーザー名、@グループ名、すべてのユーザーを指定できます(*)
type:ソフトウェア(現在のシステムで有効な設定値を指す)、hard(システムで設定可能な最大値を示す)、および-(ソフトウェアとhardを同時に設定した値を示す)
[root@localhost ~]# vim /etc/security/limits.conf   ;        
* hard nofile 65536       
* soft nofile 65536       ;      * - nofile 65536
:wq

私のはRedHat 5です.4修正後再ログインが必要で、システムによっては再起動が必要になる場合があります.
limits.confファイル構成が有効になるにはpam_を確認する必要があります.limits.soファイルが起動ファイルに追加されます.表示/etc/pam.d/loginファイルに以下のオプションがありますか.直接文末に追加されていません.
[root@localhost ~]# cat /etc/pam.d/login |grep "pam_limits.so"
session required /lib/security/pam_limits.so
[root@localhost ~]#

これはLinuxがユーザーがシステムログインを完了した後、pam_を呼び出すべきだということです.limits.soモジュールは、pam_limits.soモジュールは/etc/security/limits.confファイルで構成を読み込み、これらの制限値を設定します.
问题:修正したところ、システムがローカルにログインできないことがわかりました.リモートにログインできます.その后、次のログを见ました.
[root@mail ~]# cat /var/log/secure
...
Nov 19 13:17:23 mail sshd[3000]: error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
Nov 19 13:17:38 mail runuser: pam_unix(runuser-l:session): session opened for user amavis by (uid=0)
Nov 19 13:17:40 mail runuser: pam_unix(runuser-l:session): session closed for user amavis
Nov 19 13:17:40 mail runuser: pam_unix(runuser-l:session): session opened for user dspam by (uid=0)
Nov 19 13:17:41 mail runuser: pam_unix(runuser-l:session): session closed for user dspam
Nov 19 13:17:54 mail login: PAM unable to dlopen(/lib/security/pam_limits.so)
Nov 19 13:17:54 mail login: PAM [error: /lib/security/pam_limits.so: wrong ELF class: ELFCLASS32]
Nov 19 13:17:54 mail login: PAM adding faulty module: /lib/security/pam_limits.so
Nov 19 13:17:57 mail login: pam_unix(login:session): session opened for user root by LOGIN(uid=0)
Nov 19 13:17:57 mail login: Module is unknown
Nov 19 13:17:59 mail login: PAM unable to dlopen(/lib/security/pam_limits.so)
Nov 19 13:17:59 mail login: PAM [error: /lib/security/pam_limits.so: wrong ELF class: ELFCLASS32]
Nov 19 13:17:59 mail login: PAM adding faulty module: /lib/security/pam_limits.so
Nov 19 13:18:03 mail login: pam_unix(login:auth): authentication failure; logname=LOGIN uid=0 euid=0 tty=tty1 ruser= rhost=  user=csdp
Nov 19 13:18:05 mail login: FAILED LOGIN 1 FROM (null) FOR csdp, Authentication failure
Nov 19 13:18:22 mail sshd[3551]: Accepted password for root from 10.15.44.69 port 57696 ssh2
Nov 19 13:18:22 mail sshd[3551]: pam_unix(sshd:session): session opened for user root by (uid=0)
Nov 19 13:18:29 mail login: pam_unix(login:session): session opened for user root by LOGIN(uid=0)
Nov 19 13:18:29 mail login: Module is unknown
...

Nov 19 13:17:54 mail login: PAM [error:/lib/security/pam_limits.so: wrong ELF class: ELFCLASS32]
[root@mail ~]# getconf LONG_BIT
64
[root@mail ~]#

システムは64ビットで、上/etc/pam.d/loginは64ビットファイルが存在するディレクトリ、すなわち
[root@localhost ~]# cat /etc/pam.d/login |grep "pam_limits.so"
session required /lib64/security/pam_limits.so
[root@localhost ~]#

変更後に正常に戻る
カーネルパラメータはファイル記述子にも制限があり、設定値がカーネルの制限より大きい場合はだめです.
file-maxのカーネルパラメータを検索するには、次の手順に従います.
[root@alille-654-1-41-1 bin]# sysctl -a|grep file-max
fs.file-max = 753776
[root@alille-654-1-41-1 bin]#

file-maxのカーネルパラメータを変更するには:
[root@alille-654-1-41-1 bin]# sysctl -w file-max=65535    ;  
[root@alille-654-1-41-1 bin]# vim /etc/sysctl.conf         ;  
fs.file-max = 65535

linuxの下にアプリケーションを配置するとき、socket/file:can't open so many filesの問題に遭遇することがあります.実はlinuxにはファイルハンドルの制限があります(winxpのように).また、デフォルトはそれほど高くありません.一般的には1024ですが、本番サーバとしては簡単にこの数に達します.そのため、上記のファイルを修正してこの値を大きくする必要があります.
[root@localhost ~]# cat /proc/sys/fs/file-max 
100977
[root@localhost ~]# cat /proc/sys/fs/file-nr 
2112	0	100977
[root@localhost ~]# 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) 7922
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) 7922
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
[root@localhost ~]# ulimit -n
1024
[root@localhost ~]#

一時的にファイル数を変更する必要がある場合は、次の操作を行います.
[root@localhost ~]# ulimit -HSn 4096
[root@localhost ~]# ulimit -n
4096
[root@localhost ~]#

Hはハードサイズ、Sはソフトサイズを指定し、nは単一プロセスで最大のオープンファイルハンドル数を設定することを示し、永久修正参考上:システムファイルのオープン数を修正する
現在のシステムで最も開いているファイルの数が多いプログラムを表示する方法:
lsof(list open files)は、現在のシステムが開いているファイルをリストするツールです.端末の下にlsofを入力すると、システムが開いているファイルが表示されます.lsofはコアメモリや各種ファイルにアクセスする必要があるため、rootユーザーとして実行しなければ機能を十分に発揮できません.行ごとに開いているファイルが表示されます.条件を指定しないと、デフォルトではすべてのプロセスが開いているすべてのファイルが表示されます.
lsof-nはIPをhostnameに変換せず、デフォルトは-nパラメータeg:#lsof/GTES 11/を付けない
lsof-i条件を満たすプロセス状況を表示するためにeg:#lsof-i:22
[root@localhost ~]# lsof -n|awk '{print $2}'|sort -nr|uniq -c|sort -nr|head -5
    162 1812
    149 1827
    126 1591
    107 1823
    100 1826
[root@localhost ~]#

プログラムが開いているファイルの数を表示する方法:lsof-p pid
[root@localhost ~]# lsof -p 1812|wc -l
163
[root@localhost ~]# lsof -p 1827|wc -l
150
[root@localhost ~]#

プログラムの最大オープンファイル数を表示します:[root@alille-654-1-41-1 bin]# cat/proc/pid/limits 
[root@alille-654-1-41-1 bin]# ps -ef|grep -i "ProxyServer"
root     12091 12083 99 10:25 pts/0    05:32:45  proxyserver
[root@alille-654-1-41-1 bin]# cat /proc/12091/limits 
Max open files            65535                65535                files

ulimitコマンドの詳細
ulimitはshell起動プロセスに使用されるリソースであり、shell組み込みコマンドです.
パラメータの説明:-Hハードウェアリソースの制限を設定します.-Sソフトウェアリソースの制限を設定します.-a現在のすべてのリソース制限を表示します.-c size:coreファイルの最大値を設定します.単位:blocks-d size:データセグメントの最大値を設定.単位:kbytes-f size:作成ファイルの最大値を設定.単位:blocks-l size:メモリにロックするプロセスの最大値を設定.単位:kbytes-m size:使用可能な常駐メモリの最大値を設定.単位:kbytes-n size:カーネルが同時に開くファイル記述子の最大値を設定.単位:n-p size:パイプバッファの最大値を設定.単位:kbytes-s size:スタックの最大値を設定.単位:kbytes-t size:CPU使用時間の最大上限を設定.単位:seconds-v size:仮想メモリの最大値を設定.単位:kbytesLinux
Core dumpファイルの記録機能を有効にする
linuxでcoreファイルを開くと、プロセスが異常に終了すると、オペレーティングシステムはプロセス作業ディレクトリの下でcoreファイルを生成します.ファイル名は一般的にcoreです.プロセス番号.
一、Coreファイルの記録機能を有効にする
linuxのulimitコマンドでは、coreファイルのサイズをCcパラメータで設定します.たとえば、ulimitのCc unlimitedはcoreファイルのサイズを制限しないことを示し、coreファイルを表すバイト数を具体的な数値で設定します.
a、現在このスイッチがオンになっているかどうかを確認する
[root@localhost ~]# ulimit -c
0
[root@localhost ~]#

ulimit-c出力が0の場合は開いていません.unlimitedの場合はすでに開いています
b、開く
一時的にオン:
[root@localhost ~]# ulimit -c unlimited
[root@localhost ~]# ulimit -c
unlimited
[root@localhost ~]# ulimit -c 0
[root@localhost ~]# ulimit -c
0
[root@localhost ~]#

この機能はulimit-c unlimitedコマンドで開き、coreファイルのサイズを制限しないでください.キャンセルする場合は、コマンドulimit-c 0を実行すればいいです.
永続的に開く:
/etc/profileファイルでは一般的に、ulimit-S-c 0>/dev/null 2>&1が見つかります.上記の例によれば、その0をunlimitedに変更すればokです.直接文末に追加しなければ、保存は終了します.ソース/etc/profileで当期設定を有効にし、システムを再起動
[root@localhost ~]# vim /etc/profile
ulimit -S -c unlimited
:wq
[root@localhost ~]# source /etc/profile
[root@localhost ~]# ulimit -c
unlimited
[root@localhost ~]#

二、Coreファイルログの表示方法
通常、gdbツールを使用してこのcoreファイルを参照します.gdbはlinuxが持参したデバッグツールで、異常が発生した関数名に位置しやすいです.例えば、プロセスを実行し、異常な終了が発生すると、作業ディレクトリの下にcoreが生成されます.xxxxのファイルです.gdb表示を実行できます.
gdbプロセス名core.xxxxxは車に戻り、whereコマンドを入力します.つまり、異常時の関数呼び出しスタックがリストされます.一般的に環境の一貫性を保証するために、自機でgdbを実行してcoreファイルを参照する必要があります.
eg:gdb httpd -c core.1309
      Where
core dumpファイル名のモードは/proc/sys/kernel/core_に保存されます.patternでは、デフォルト値はcoreです.core dumpファイルの場所(/tmp/coresディレクトリに生成する場合など)echo'/tmp/cores/core'>/proc/sys/kernel/core_を変更するには、次のコマンドを使用します.pattern