概要
Too many open files
のエラーが出た際の対策として、ファイルディスクリプタの上限を変更することがあります。
方法として以下の4つがあります。
ulimit
で変更する/etc/security/limits.conf
で設定する- systemdのサービスの設定で
LimitNOFILE
を設定する - systemdの全体設定で
DefaultLimitNOFILE
を設定する
環境
- Ubuntu v22.04.1
- Nginx v1.18.0
ファイルディスクリプタ数の確認方法
ファイルディスクリプタ数は以下の方法で確認ができます。
現在ログイン中のユーザの場合
$ ulimit -n 1024
特定のプロセスの場合
$ cat /proc/{プロセスID}/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds ... Max open files 1024 524288 files ...
Max open files
が上限です。
方法
1. ulimit
で変更する
現在ログイン中のユーザのファイルディスクリプタ数を上げる際に一番手軽な方法です。
$ ulimit -n 1024
となっているので、数値を引数に入れれば設定できます。
$ ulimit -n 2048 $ ulimit -n 2048
デメリットとしては再度ログインしたり再起動するとリセットされてしまう点です。
2. /etc/security/limits.conf
で設定する
リセットされてしまわないように永続化する方法です。
sshやsudoなどPAM認証を介すものに関してはこちらを設定することで永続的な設定が可能となります。
/etc/security/limits.conf
に以下を追記します。
* soft nofile 65536 * hard nofile 65536
*
にすると全ユーザが対象になります。*
の代わりに特定のユーザ名を入れることで対象を絞ることもできます。
動作確認
再度ログインしてみると反映されています。
vagrant@ubuntu-jammy:~$ logout ubuntu_jammy $ vagrant ssh Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-48-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Sun Oct 9 07:28:30 UTC 2022 System load: 0.00439453125 Processes: 106 Usage of /: 3.6% of 38.70GB Users logged in: 0 Memory usage: 24% IPv4 address for enp0s3: 10.0.2.15 Swap usage: 0% 0 updates can be applied immediately. Last login: Sun Oct 9 07:19:41 2022 from 10.0.2.2 vagrant@ubuntu-jammy:~$ ulimit -n 65536
デメリットではないですが気をつける点としてPAM認証を介すものに対して設定されるので、daemon系のプロセスには反映されません。
3. systemdのサービスの設定でLimitNOFILE
を設定する
前述のようなPAM認証を介さないdaemon系のプロセスについては、systemdで設定を行います。
nginxのユニットファイルは/etc/systemd/system/multi-user.target.wants/nginx.service
にあります。
[Unit] Description=A high performance web server and a reverse proxy server Documentation=man:nginx(8) After=network.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed [Install] WantedBy=multi-user.target
Service
ディレクティブにLimitNOFILE
を設定します。
[Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed LimitNOFILE=60000
設定をリロードして再起動します。
$ sudo systemctl daemon-reload
$ sudo systemctl restart nginx
動作確認
期待通り上限が変更されていました。
$ ps aux | grep [n]ginx root 2886 0.0 0.1 55200 1676 ? Ss 07:37 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; www-data 2887 0.0 0.5 55832 5460 ? S 07:37 0:00 nginx: worker process www-data 2888 0.0 0.5 55832 5460 ? S 07:37 0:00 nginx: worker process $ cat /proc/2886/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 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3722 3722 processes Max open files 60000 60000 files ...
4. systemdの全体設定でDefaultLimitNOFILE
を設定する
先程の派生みたいなものですが、サービスごとの個別設定ではなくsystemdを利用するサービス全てでデフォルト値を底上げするパターンです。
/etc/systemd/system.conf
にDefaultLimitNOFILE
がコメントアウトされています。
#DefaultLimitSTACK= #DefaultLimitCORE= #DefaultLimitRSS= #DefaultLimitNOFILE=1024:524288 #DefaultLimitAS=
softLimit:hardLimit
の順に設定されています。これをアンコメントして設定します。
DefaultLimitNOFILE=60000:524288
設定をリロードして再起動します。
$ sudo systemctl daemon-reload
$ sudo systemctl restart nginx
動作確認
期待通り上限が変更されていました。
$ cat /proc/1474/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 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3722 3722 processes Max open files 60000 524288 files ...
ただこれは適切なリソース制限がされなくなるので、前述の個別設定の方が適切です。
まとめ
ファイルディスクリプタ数の上限を変更する4つの方法を説明しました。