Home > アーカイブ > 2013-02

2013-02

nginx で Too many open files エラーに対処する

この記事の所要時間: 754

nginx では1プロセスで多くのアクセスを捌くので、アクセス数が増えるとToo many open filesエラーが発生することがあります。
ここでは対処法と調べた内容を残しておきます。

1. fs.file-max の確認

まず fs.file-max の値を確認しておきます。fs.file-max は、システム全体でのファイルディスクリプタの上限数となっており、この値以上のファイルディスクリプタは確保することができません。
現在設定されている値は以下で確認できます。

$ cat /proc/sys/fs/file-max
167488

通常は上記の値で問題無いと思いますが、もしこの値が不足しているようなら設定値を更新します。

$ sudo -s
# echo 320000 > /proc/sys/fs/file-max
# cat /proc/sys/fs/file-max
320000

再起動時に有効となるように /etc/sysctl.conf に記述しておきます。

$ sudo vim /etc/sysctl.conf
fs.file-max=320000

2. worker_rlimit_nofile の指定

次はプロセス毎のファイルディスクリプタ上限数を増やします。
nginx ではプロセス毎のファイルディスクリプタ上限数を指定する設定項目 worker_rlimit_nofile が用意されているので、これを記述します。設定する値は worker_connections の3〜4倍くらいが良いでしょう。

$ sudo vim /etc/nginx/nginx.conf

worker_rlimit_nofile  4096;

(snip)

events {
      worker_connections  1024;
}

設定変更後は nginx をリスタートしておきます。

$ sudo /etc/init.d/nginx restart

設定値が反映されているか確認しておきます。ワーカープロセスのプロセスID で limits を確認します。下記では「Max open files」の行がこれに当たるのですが、Soft Limit と Hard Limit 双方とも worker_rlimit_nofile で指定した値が設定されていることが分かります。

$ ps ax | grep nginx | grep worker
17064 ?        S      0:00 nginx: worker process                   

$ cat /proc/17604/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            10485760             unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             8191                 8191                 processes 
Max open files            4096                 4096                 files     
Max locked memory         32768                32768                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       8191                 8191                 signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0   

プロセス毎のファイルディスクリプタ上限数を設定する方法として、ulimit コマンドや /etc/security/limits.conf による記述などがあるのですが、これらは環境によってはデーモン起動では適用されなかったり、起動ファイルに記述する必要があるなど注意が必要です。

nginx ではワーカープロセス初期化処理にて worker_rlimit_nofile で指定した値をsetrlimit(2) で設定するので、ulimit などで指定された値は上書きされます。(ソフトリミット、ハードリミット両方)

参照

おまけ

調べている中で色々と試したのでメモ。
もし同じようなことを試すなら、壊しても問題無い環境で行ないましょう。(私は AWS で EC2 インスタンス(AmazonLinux)を起動して試しました。) 

fs.file-max を 0 にする。

$ sudo -s
# echo 0 > /proc/sys/fs/file-max
# cat /proc/sys/fs/file-max
0
  • 元のシェルは動作している
# ls -a
. ..
  • 一般ユーザに戻るとだめ
# exit
$ ls -la
-bash: start_pipeline: pgrp pipe: Too many open files in system
-bash: /bin/ls: Too many open files in system
  • SSH でログインできない

ローカルから別コネクションでSSHでログインしようとしたのですが、ダメでした。

% ssh ec2-user@xxx.xxx.xxx.xxx
ssh_exchange_identification: Connection closed by remote host

結局、Management Console からインスタンスを stop & start することに。。。

  • /var/log/messages にログが記録される。

再起動後に /var/log/messages を見ると下記のようなログが記録されていました。

Feb 11 13:36:51 ip-10-121-3-15 kernel: [  221.357976] VFS: file-max limit 0 reached

nginx で worker_rlimit_nofile が適用される箇所

nginx が worker_rlimit_nofile で指定した値をカーネルに設定する箇所をソースコードから探してみました。(nginx1.2.7)
src/os/unix/ngx_process_cycle.c の861行目付近でこの処理が行われています。root でマスタープロセスを実行している場合は、この箇所ではまだ root ユーザで動作しているので、ソフトリミット、ハードリミット共に worker_rlimit_nofile で指定した値が設定されています。

  • コメント (Close): 0
  • トラックバック (Close): 0

Home > アーカイブ > 2013-02

検索
フィード
メタ情報

Return to page top