
多くの TCPIP および Web チューニング ガイドでは、「開いているファイルが多すぎます」というエラーが発生した場合に、ファイル記述子の最大数を増やすことを推奨しています。
しかし、「lsof -i」の出力にTIME_WAITが表示されません
TIME_WAITがファイル記述子を消費することを知っている人はいますか?
答え1
ファイル記述子は、アプリケーションがソケットから読み取り/書き込みを行うために使用されます。したがって、アプリケーションが close() を呼び出すと、ファイル記述子はすぐに解放されます。
一方、アプリケーションがshutdown()を呼び出すと、ファイル記述子は有効なままになり、アプリケーションは引き続きソケットから読み取り/書き込みを行うことができます。
引用元https://oroboro.com/file-handle-leaks-server/:
誤解: TCP TIME_WAIT のソケットがファイル ハンドルを人質にしている
TCP/IP ソケットを閉じても、オペレーティング システムはソケットをすぐに解放しません。複雑な理由により、ソケット構造は数分間循環から外しておく必要があります。これは、ソケットが閉じられた後に IP パケットがそのソケットに到着する可能性がわずかにあるためです。オペレーティング システムがソケットを再利用すると、その接続の新しいユーザーのセッションは、他のユーザーの失われたパケットの影響を受けることになります。
しかし、これではファイル ハンドルが開いたままになりません。ソケットのファイル記述子を閉じると、ファイル記述子自体も閉じられます。「開いているファイルが多すぎます」というエラーは表示されません。開いているソケットが多すぎると、サーバーが新しい接続を受け入れなくなる可能性があります。これに対処する方法はいくつかありますが (ソケットの再利用を許可するか、TCP TIME_WAIT を下げる)、ファイル ハンドルの制限を上げるという方法はありません。
誤解:ファイルハンドルの解放には時間がかかる
これは、TCP TIME_WAIT 神話に関連しています。ファイル ハンドルを閉じると、オペレーティング システムがハンドルを解放するまでしばらく待たなければならないという誤った考えです。
ファイル ハンドルを閉じると、リソースを解放する OS メソッドが呼び出され、OS はそのリソースを直ちに解放するか、ソケットの場合のように後で解放することもあります。ただし、close() はファイル ハンドル テーブル内のファイル ハンドルを直ちに解放します。プロセスはファイル ハンドル テーブルを完全に制御しており、独自のファイル記述子テーブル内のスロットを解放するために何かを待つ必要はありません。
答え2
TIME_WAIT は TCP 状態であり、ファイル記述子を消費しません。ただし、TIME_WAIT のソケットはファイル記述子を消費します。ソケットは、UNIX のほぼすべてのものと同様にファイルです。Linux の場合は、ソケットの有効期限 (待機時間の長さ) を調整したり、ソケットのリサイクルを有効にしたりできます/proc/sys/net/ipv4/
。
特に興味深いのはおそらく次の 2 つの項目です。
sysctl -w net.ipv4.tcp_tw_recycle=1
sysctl -w net.ipv4.tcp_tw_reuse=1
いつものように、可能であれば事前にテストしてください。