たごもりすメモ

コードとかその他の話とか。

Apache2.2(2.3-trunk)のビルド

mod_proxy_balancerを試すときのApacheのビルドの概要をごく簡単にリストアップ。何度も忘れて繰り返したミスを中心に。

  1. apr/apr-utilのtrunkを持ってきて srclib 下に入れておく
  2. trunkの場合はautoconf/libtoolを入れておいてbuildconfから始めること
  3. configureオプション
    • --prefix=/path/to/install --with-mpn=prefork --enable-mods-shared=all --enable-proxy=shared
    • proxy関連はこれだけで全部有効になる

関連リンク

間違ったworkerに配送されるバグの確認

とりあえずはてなの中の人が見付けたバグの再現をとってみた。
焦点はBugzillaの40910に該当する問題なのかどうか。

試した設定は以下の通り。全てのバージョンのApacheで(ServerRoot以外)全く同じものを用いている。
以下関係するホスト。
balancer0(192.168.50.10), worker1(192.168.50.11), worker2(192.168.50.12), worker11(192.168.50.111)
各々のホストのDocumentRootには hostname.txt が置いてあって、中身はホスト名が書かれているだけ。

ProxyPass /r1/ balancer://testcluster1/ stickysession=SESSID
ProxyPass /r2/ balancer://testcluster2/ stickysession=SESSID
<Proxy balancer://testcluster1>
  BalancerMember  http://worker1  loadfactor=10  route=w01
  BalancerMember  http://worker2  loadfactor=10  route=w02
</Proxy>
<Proxy balancer://testcluster2>
  BalancerMember  http://worker11  loadfactor=10  route=w11
</Proxy>

結果は以下の通り。

  • 2.2.3
    • configtestの結果: Syntax OK のみ
    • /r2/hostname.txt にアクセスしても worker1 に配送されてしまう
      • URIパラメータにより SESSID=HOGEHOGE.w11 を指定してもworker1に行く
    • バランサーの設定記述順序を逆にし worker11 を worker1 の前に記述すると正しく動作する
  • 2.2.4
    • 2.2.3と完全に同様
  • trunk
    • configtestの結果:Syntax OK のみ
    • /r2/hostname.txt にアクセスすると、正しく worker11 に配送される
  • trunk のソースに対してBugzillaの40910のパッチによる修正箇所をコメントアウトしたもの
    • configtestの結果:以下のwarningが出力される
[warn] worker http://worker1 already used by another worker
    • 動作自体は2.2.3および2.2.4と同様

ということで、目星をつけた修正がこの問題に対応していることが確認できた。
対処法としては以下の通り。

  • trunkを使う
    • 普通無理だよなあ
  • 2.2.4 に該当パッチを当てる
    • それもどうかと
  • MLに2.2.xにもbackportしてよとお願いする
    • 誰か(ぇー
  • 設定ファイルを書く場合には順序に注意しましょう
    • 果てしなくバッドノウハウくさい
    • しかもバランサー毎にファイルが分かれていたりすると茨の道

ホスト名・IPアドレス表記・ポート番号指定などが全て影響を受けるので、みなさん注意しましょう。

既知の問題およびHowToまとめ

結論を先に書くと「trunk使え」か?(ぇー
まあ2.2.4でもなんとかなるかも。2.2.3以前だとかなり注意しないと、道を踏み外した瞬間に穴にハマりそう。
で、以下リスト。

trunkで修正されているもの

  • Critical: リクエストが間違ったワーカーに配送される Bugzilla 40910
    • ポート番号に限らずホスト名(/IPアドレス)の部分一致でも発生する
    • stickysession/routeによるルーティングが有効でもこのバグにひっかかる
    • 部分一致するホスト名のうち長いものを設定ファイル上で先に書いておくと回避できる

2.2.4で修正済みのもの

  • Critical: 一度エラーになったセッションがTimeoutを過ぎてもエラーから復帰しない Bugzilla 38962
    • 新規セッションは問題ない
    • 本来はTimeout時間経過後は再度ワーカーに振られないとならない
  • Critical: セッションID(stickysession指定パラメータ)がURIパラメータにある場合のparse失敗 Bugzilla 40400
    • URIパラメータのデリミタとして'&'を認識せず、セッションIDが正しくparseされない
    • 2.2.3以前ではURIにセッションIDを入れる場合(Cookieが使えない携帯など)、以下のどちらかにする必要がある

未修正の問題

  • セッションIDがCookieに含まれ、かつURLエンコードされていない場合にルーティングがうまく動作しない Bugzilla 34844
    • デリミタであるドット('.')を正しく検出できないため
    • ASP.NET 3.0 がこのような動作らしい(今も?)
  • graceful restartで正しく設定が変更されない(かも) Bugzilla 42621
    • 設定を変更したら graceful ではなく restart しましょう
    • graceful stop -> start でもいいのかな?(未確認)
  • stickysessionで指定するパラメータ名の大文字小文字について Bugzilla 41897
    • 以下のような場合に、指定した方ではない間違ったパラメータがstickysessionとして扱われてしまう
      • stickysession=JSESSIONID
      • JSESSIONID というパラメータがCookieに存在する
      • jsessionid というパラメータがURIパラメータに存在する
    • case-sensitive/insensitiveな処理が混在している模様
      • パラメータ名混ぜるな危険
  • stickysessionの固有ID部分とルーティング先指定子とのデリミタがドット('.')固定 Bugzilla 42513
  • CLOSE_WAITなソケットが残留する(場合がある?) Bugzilla 41771
    • 再現条件などがいまのところ不明
    • 永遠に残留するようならプールを使い切ってしまう危険がある か?
  • URIとして無効な文字列がパスに含まれている場合に処理に失敗する Bugzilla 41614
    • SEOでどうのこうの という目的らしいが...

BalancerManager関係

  • MPM Workerの場合に BalancerManager を用いて行った設定が巻き戻る Bugzilla 39907
    • 未修正
  • BalancerManagerを開くときに死んでいるworkerがあるとTimeoutを待ってしまう Bugzilla 41764
    • 報告のみ 未修正
  • BalancerManagerが無効なworkerを "Ok" と表示してしまう Bugzilla 42668
    • 報告のみ 再現報告無し 未修正

その他Tips/設定時の注意点など

  • workerへのリクエストのHost:ヘッダには元リクエストのものは継承されない Bugzilla 38096
    • 多くの場合については正しい挙動だと思われる
      • どうなって欲しいかは用途による
      • 通常バックエンドサーバは特定のVirtualHostのリクエストのみ受け付けるのでは? ということ
    • 必要ならProxyPreserveHostディレクティブを使用する
  • stickysession内にルーティング先を指定できない場合 Bugzilla 38357
    • アプリケーション側の都合でルーティング先をsessionidに埋められない場合
    • mod_headerを使用してApache側でCookieを操作する
      • 2.2.4 以降で実装されている
      • Bugzilla 39806 によるパッチ等を参照のこと
  • ProxyPassおよびの記述におけるスラッシュの扱いについて Bugzilla 39203
  • ホットスタンバイノードの記述を行う方法 Bugzilla 39304
    • ProxyPassディレクティブの無い <Proxy balancer://..> の記述を行う方法も兼ねる か?
    • ProxySetディレクティブを使いましょう
  • stickysession指定はVirtualHost内でないと行えない? Bugzilla 41764
    • ProxySetディレクティブで解決するような気がする(未確認)
  • アプリケーションのデプロイ時に全ノードを一気に落とさないよう注意
  • mod_proxy_balancerに独自の振り分けロジックを追加

とりあえず書いてみたが

なんか汚い。リストが深くなった場所が特に悲惨だ。別のデザインだともっとマシな見た目になるのかなあ。

追記: はてなスタイルにしてみたら見た目がかなりマシになった。もうコレでいいや。w