Akira's Tech Notes

Java/JVM | GNU/Linux | Emacs/Lisp | 知的好奇心駆動

header-icon
ネイティブでない日本語で思い付くことや気になることをダラダラ書く、体裁とかは気にしない。読みづらいと感じた時に随時更新する。

[メモ]ApacheでbackendとのKeepAliveをOFFにする

次のような構成でApacheとAPサーバ間のHTTP KeepAliveが有効にすると

  1. LBの振り分けが偏る可能性がある
  2. 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

Comments