Apache リバース プロキシ Java アプリケーション サーバー CLOSE_WAIT 接続

Apache リバース プロキシ Java アプリケーション サーバー CLOSE_WAIT 接続

Java アプリケーション サーバー (GlassFish) のリバース プロキシとして Apache をセットアップしましたが、アイドル状態の開発システムでも CLOSE_WAIT 状態の接続が約 100 件あることに気付きました。

sudo netstat -n -e -p -a -t | grep httpd | grep CLOSE_WAIT | wc -l

次の HTTP プロキシ設定を使用しています:

ProxyPass /myapp http://localhost:8080/myapp ttl=20 max=1 smax=0
ProxyPassReverse /myapp http://localhost:8080/myapp

なぜこれらすべての接続が残っているのでしょうか? 「ttl=20 max=1 smax=0」に設定しているので、アイドル状態のシステムではすべての接続がクリーンアップされると考えていました。アプリケーション サーバーは接続をクリーンアップする役割を果たしていないのでしょうか?

答え1

これはmod_proxy の既知の問題、2011年以来。

Apache が常に最初に FIN を送信できるように、TTL はアプリケーションのキープアライブよりも短くする必要があります。

もう 1 つの難点は、接続が実際にどの時点で閉じられるかが定義されていないことです。

ttl - 非アクティブな接続とそれに関連する接続プールエントリの存続時間(秒単位)。この制限に達すると、接続は再び使用されなくなり、しばらく後

答え2

私も同様の問題に遭遇したので、Apache に関する理由を探しています。Apache の prefork が原因と思われます。

解決策としては、CLOSE_WAIT の問題を解決する Nginx を使用しました。ただし、TIME_WAIT の数 (約 20,000) は、Java アプリケーションが接続を処理する方法に問題があることを示しています。Nginx を使用すると、サーバーとアプリケーションのパフォーマンスが大幅に向上します。

誰かが技術的な詳細を添えてこの回答を改善してくれることを願っています。

答え3

これらの CLOSE_WAIT 接続は無効です。サーバーは、さらにパケットが到達した場合に備えて、これらの接続を TCP スタック内に保持しているだけです。古き良き時代では、Solaris サーバーは、ファイル記述子が大きすぎるとファイル記述子を使い果たし、システムがクラッシュしていました。カーネルで許可されるファイル記述子の合計数を増やし、CLOSE_WAIT 接続のクリーンアップ間隔を短縮する必要がありました。

現在では、ファイル記述子のデフォルトの数は通常、これを無視できるほど十分に大きくなっています。ただし、クリーンアップ構成を減らすことができるため、CLOSE_WAIT 接続の数も減ります。

これら (Glassfish、Tomcat、JBoss など) では、その性質上、多数の接続を使用し、それらを再利用しません。ほとんどの場合、無視しても問題ありません。

関連情報