突然新しい接続を拒否するサービスや「Too many open files」と書かれているサービスは、必ずしもメモリの問題があるわけではありません。ファイルディスクリプタの制限に達している可能性があります。Linuxでは、ソケット、ログ、ファイル、時にはパイプも、1つのディスクリプタを消費します。
ulimit -nコマンドは、現在のシェルの制限を表示します。これは、既に起動しているサービスの制限を証明するものではありません。systemdで管理されているデーモンに対しては、何かを変更する前にプロセス、ユニット、および永続的な設定を確認してください。

シェルとプロセスの制限を読む
ターミナルで、ソフトリミットとハードリミットを区別することから始めます。前者はプロセスによって引き下げられることがあります。後者は、特権のないユーザーが超えることのできない上限を設定します。
ulimit -Sn
ulimit -Hn
結果が1024であれば、インタラクティブなセッションには十分かもしれません。しかし、プロキシ、Webサーバー、または多数の接続をオープンにしているアプリケーションには、すぐに不足します。フォーラムで見つけた値をコピーしないでください:サービスが使用している量を測定することから始めてください。
そのPIDを特定し、適用されている制限を確認します:
systemctl show nginx -p MainPID
sudo grep 'Max open files' /proc/1234/limits
sudo ls /proc/1234/fd | wc -l
1234をsystemdから返されたPIDに置き換えます。/proc/1234/fdのカウントは、オープンしているディスクリプタの数のスナップショットを提供します。これをMax open filesと比較します。小さな乖離は、単なる遅延の印象よりも飽和の方がより良く説明します。
変更する前にsystemdの制限を確認する
systemdサービスは、SSHセッションの値を自動的には取得しません。ユニットはLimitNOFILEを定義するか、グローバル値を継承することがあります。実際の値を表示します:
systemctl show nginx -p LimitNOFILE
systemctl cat nginx
ユニットが低い制限を表示し、ログが開くエラーを確認する場合は、パッケージによって提供されたファイルを変更するのではなく、オーバーライドを作成します:
sudo systemctl edit nginx
次に、このセクションを追加し、アプリケーションに合わせた値を設定します:
[Service]
LimitNOFILE=65535
本番で公開されるサービスの場合は、2番目のSSHセッションを開いたままにしてください。ユニットの誤りや失敗した再起動によってアクセスができなくなることは避けなければなりません。アプリケーションのドキュメントも確認してください。一部のアプリケーションは、systemdとは異なる独自の上限を課すことがあります。
再起動して、実際に適用された値を確認する
オーバーライドの後、設定をリロードし、影響を受けるサービスのみを再起動します:
sudo systemctl daemon-reload
sudo systemctl restart nginx
systemctl show nginx -p LimitNOFILE
systemctl status nginx --no-pager
最後に、新しいPIDで/proc/PID/limitsを再度確認します。systemdでLimitNOFILEが65535であっても、プロセスが1024のままである場合、古いPID、異なるサービス、または中間の監視者を見ている可能性があります。
制限を引き上げる前に行うべき確認
journalctl -u nginxまたはアプリケーションのログで正確なエラーを確認してください。- 負荷のピーク前と後のオープンディスクリプタの数を測定してください。
- すべてのマシンのサービスのためではなく、特定のユニットのために制限を引き上げてください。
- オープン状態を保持する接続、ファイル、ソケットを監視してください:ディスクリプタのリークはアプリケーションで修正する必要があります。
制限を上げることでサービスの突然の終了を防ぎますが、ファイルを開いたままにするプロセスの修正にはなりません。観察された値とログの抜粋を保存してください。それらは、制限が低すぎたのか、サービスを修正する必要があるのかを判断するのに役立ちます。