highlight.xcode

2021年5月31日月曜日

nginx の「Too many open files」エラーの対処



Debian buster 上の nginx の設定を煮詰め直すのに色々と調べた時のメモ。

nginx と言えばC10K問題の解決、を目的の 1つとして開発された I/O 特化型の Web サーバーです。しかし、当然の事ですが OS 等による制約は超えられない訳で、その制約の内の 1つが、ファイルディスクリプタの制限(扱えるファイル数の上限)です。

そしてそのファイルディスクリプタの制限についての設定は、nginx をユーザプロセスとして実行しているか、デーモンプロセスとして実行しているかにより異なります。今回、色々と調べていたら、その辺を混同して解説している情報が多かったので、整理の上メモっておきます。


まずは結論から。
  1. OS(Debian buster)自体の制限を設定。
  2. ユーザープロセスとして実行している場合は、実行ユーザーの制限を設定。
  3. デーモンプロセスとして実行している場合は、デーモンの制限を設定。
  4. nginx の制限を設定。
至極当たり前の事しか書いてない気もしますが、整理が目的なので…。ユーザープロセスとして実行する場合は 2を、デーモンプロセスとして実行する場合は 3を行います。


OS(Debian buster)自体の制限値を確認するには、以下のコマンドを実行します。
# cat /proc/sys/fs/file-max
9223372036854775807
なかなか恐ろしい数値が返ってきましたが、多分、全開って事なんだと思います。

OS(Debian buster)自体の制限を設定する方法は、"/etc/sysctl.conf"に設定を追加するだけ。ファイルを開き、最終行の下へ以下を追加します。
(省略)
# Limit of file descriptor
fs.file-max = 2147483647
再起動で反映されます。


ユーザープロセスとして実行する場合の設定です。

ユーザープロセスの制限値を確認するには、以下のコマンドを実行します。
$ ulimit -n
1024
ソフトリミット(ユーザーが設定可能な値の現在値)を確認するには、以下のコマンドを実行します。
$ ulimit -Sn
1024
ソフトリミットを設定するには、以下のコマンドを実行します。この値はハードリミットの値までが設定可能です。
$ ulimit -Sn 2048
$ ulimit -Sn
2048
ハードリミット(ユーザーが設定可能な値の上限値)を確認するには、以下のコマンドを実行します。
$ ulimit -Hn
1048576
ハードリミットを設定するには、以下のコマンドを実行します。が、一般ユーザは減らす事しか出来ないので、実際には実行してはいけません。ハードリミットの上限を増やしたい場合は、スーパーユーザーで設定を行います。
$ ulimit -Hn 2048
$ ulimit -Hn
2048
各ユーザーのハードリミット(ソフトリミットも)を設定するには、スーパーユーザーで"/etc/security/limits.conf"ファイルを開き、ファイル下部に以下の様に記述します。"item"の"nofile"がファイルディスクリプタの上限です。
(省略)
#<domain>      <type>  <item>         <value>
user            hard   nofile         32768
user            soft   nofile         1024
ユーザーのログイン時に適用される為、設定したユーザーをログインし直せば反映されます。


デーモンプロセスとして実行する場合の設定です。

デーモンプロセスの制限値を確認するには、以下のコマンドを実行します(nginx の場合)。
# grep "open files" /proc/`pidof -s nginx`/limits
Max open files            1024                 524288               files
デーモンプロセスの制限値を設定するには、systemd の設定ファイルへ記述します。Debian buster の場合は"/etc/systemd/system/nginx.service.d"ディレクトリ以下の"*.conf"ファイルです。ディレクトリ、及び設定ファイルが既存する場合は、その内容を確認して下さい。ディレクトリや設定ファイルが存在しない場合は、新規に作成します。
# mkdir /etc/systemd/system/nginx.service.d
# touch /etc/systemd/system/nginx.service.d/override.conf
"/etc/systemd/system/nginx.service.d/override.conf"を開き、以下の様に記述します。
[Service]
LimitNOFILE=65536


nginx 側の設定を行います。"/etc/nginx/nginx.conf"を開き、以下の様に追加します。追加箇所はトップレベルです。ここではワーカープロセスの数を 2つ、ワーカープロセス当たりの制限値に 32768 を指定しています。
worker_processes 2;
worker_rlimit_nofile 32768;
nginx を再起動し、設定を確認します。
# systemctl daemon-reload
# systemctl restart nginx
# grep "open files" /proc/`pidof -s nginx`/limits
Max open files            32768                32768                files
# ps aux | grep nginx | grep -v grep
root      8515  0.0  0.0  68724  1764 ?        Ss   15:59   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data  8516  0.0  0.2  69384  5900 ?        S    15:59   0:00 nginx: worker process
www-data  8517  0.0  0.2  69384  5900 ?        S    15:59   0:00 nginx: worker process
ワーカープロセスの制限値が 32768、マスタープロセスが 1つ、ワーカープロセスが 2つ実行されている事が確認できます。

0 件のコメント:

コメントを投稿