Table of Contents
次のような構成でApacheとAPサーバ間のHTTP KeepAliveが有効にすると
- LBの振り分けが偏る可能性がある
- LBの無振り分け先の切り替えに影響が生じる可能性がある、詳細は こちらの記事 を参照してください。
のような不都合があります。
+----------+ +------------+ +-----------+ +-------------+ | Client +---------> Apache +--------> LB +-----> AP Server | +----------+ +------------+ +-----------+ +-------------+
とい言うわけでApacheとAPサーバ間KeepAliveをOFFにする方法を調査した。
1 Apache側でKeepAliveを制御する
ProxyPass
ディレクティブの keepalive
パラメータが期待通り動作しないので迷っていた、
しかしドキュメントによると
バックエンドサーバと Apache の間にファイアーウォールがある場合には、 このパラメータを 使ってください。ファイアウォールは往々にして、 非活動状態のコネクションを落とそうとし ます。 このフラグは OS に指示して、KEEP_ALIVE メッセージを非活動状態の コネクションで も送るようにします。これによってファイアウォールによってコネクションが 落とされること を防げます。keepalive を有効にするには、このプロパティを On にしてください。
HTTP KeepAliveに関係しそうに見えたが、実はあんまり関係ないのようです。 TCPレベルでコネクションをファイアウォールによる切断を防ぐためのパラメータです。
更に調べると mod_proxy_http
モジュールの環境変数にHTTP KeepAliveに関係するものが
出てきた。
- force-proxy-request-1.0 プロキシがバックエンドに HTTP/1.0 でリクエストを送るようにし、HTTP/1.1 の機能を無効にします。
- proxy-nokeepalive プロキシがリクエスト終了後にバックエンドとの接続を切るようにします。
よし!これだそう。次のように設定したらうまくできた。
<Location /test/> ProxyPass http://dummyhost:8080/app1/ SetEnv proxy-nokeepalive 1 </Location>
これで、ApacheからAPサーバへのHTTPリクエストヘッダに Connection: close
が付与される
ようになりました。 tcpdump
でパケットのやり取りを確認すると、ちゃんと毎回クライアン
トのからコネクション切断するためのfinパケットが送信されることを確認しました。
2 APサーバ側にてKeepAliveを制御する
一般的にAPサーバ側でもKeepAliveの設定が可能です。
流れ的に、HTTPレスポンスのHTTPヘッダに Connection: close
を付与して返すことで
リクエスト側にコネクション切断する旨を伝える。
Tomcat起動時に次のJavaオプションを付けるとHTTP KeepAliveがOFFになります。
-Dorg.apache.coyote.http11.Http11Protocol.MAX_KEEP_ALIVE_REQUESTS=1