web-dev-qa-db-ja.com

Apacheプロキシ負荷分散バックエンドサーバーの障害検出

これが私のシナリオです(私の前任者によって設計されました):

複数の混合バックエンドWebサーバー(Apache、IIS、Tomcatなど)のリバースプロキシの役割を果たす2つのApacheサーバー。複数のバックエンドWebサーバーを使用しているサイトがいくつかあります。そのような場合は、次のようにします。

<Proxy balancer://www.example.com>
    BalancerMember http://192.168.1.40:80
    BalancerMember http://192.168.1.41:80
</Proxy>
<VirtualHost *:80>
    ServerName www.example.com:80
    CustomLog /var/log/Apache2/www.example.com.log combined
    <Location />
        Order allow,deny
        Allow from all
        ProxyPass balancer://www.example.com/
        ProxyPassReverse balancer://www.example.com/
    </Location>
</VirtualHost>

したがって、この例では、プロキシサーバーの構成に1つのサイト(www.example.com)があり、そのサイトは2つのバックエンドサーバー192.168.1.40と.41のどちらか一方にプロキシされています。

私はこれを評価して、すべてのWebサービスでフォールトトレラントであることを確認しています(この理由で、2つのリバースプロキシサーバーを共有IPクラスターに既に配置しました)。バランスのとれたバックエンドサーバーもフォールトトレラントです。しかし、バックエンドの障害検出(および障害が発生したバックエンドサーバーを回避するロジック)がmod_proxy_balancerモジュールに組み込まれているかどうかを理解するのに問題があります...

したがって、192.168.202.40がダウンした場合、Apacheはこれを検出し(失敗したリクエストを最初に受け取るかどうかを理解します)、すべてのリクエストを他のバックエンド192.168.202.41に自動的にルーティングしますか?それとも、失敗したバックエンドと運用バックエンドの間でリクエストのバランスを取り続けますか?

Apacheのドキュメントに mod_proxy および mod_proxy_balancer の手掛かりが見つかりました。これは、障害を検出できることを示しているようです( "maxattempts =フェイルオーバーの最大試行回数。 "、" failonstatus = HTTPステータスコードの単一またはカンマ区切りのリスト。これを設定すると、バックエンドがリスト内のステータスコードを返すときにワーカーが強制的にエラー状態になります。 ")ですが、数日検索した後、バックエンドの障害とリカバリを検出する(または少なくとも「すべき」)ことを確認する決定的な言葉は見つかりませんでした。

検索結果の大部分はAJPプロトコルを使用してトラフィックをバックエンドサーバーに渡すことを参照していると言いますが、これは明らかに障害検出をサポートしています-しかし、私のバックエンドはApache、IIS、Tomcatなどの混合であり、私はそれらの多くがAJPをサポートしていないことをかなり確信しています。また、Windows 2k3/2k8とLinux(主にUbuntu Lucid)ボックスが混在しており、さまざまな要件のさまざまなアプリケーションを実行しているため、BackhandやLVSなどのアドオンモジュールは選択できません。

また、このような新しいテストサイトを作成して、この機能を実験的にテストしました。

<Proxy balancer://test.example.com>
    BalancerMember http://192.168.1.40:80
    BalancerMember http://192.168.1.200:80
</Proxy>
<VirtualHost *:80>
    ServerName test.example.com:80
    CustomLog /var/log/Apache2/test.example.com.log combined
    LogLevel debug
    <Location />
        Order allow,deny
        Allow from all
        ProxyPass balancer://test.example.com/
        ProxyPassReverse balancer://test.example.com/
    </Location>
</VirtualHost>

192.168.1.200は、バックエンドの障害をシミュレートするために、Webサーバーを実行していない偽のアドレスです。テストサイトは、さまざまなクライアントマシンの束に対して問題なく提供されましたが、LogLevelがdebugに設定されていても、バックエンドサーバーの1つがダウンしていることを検出したことを示すログが何も表示されませんでした...そして本番サイトに影響を与えることなく、負荷分散されたバックエンドをメンテナンスのために(一度に1つずつ)ダウンさせることができることを100%確認したいと思います。

14
Jon Heese

http://httpd.Apache.org/docs/2.4/mod/mod_proxy.html セクション「BalancerMemberパラメータ」、property = retry:

バックエンドサーバーへの接続プールワーカーがエラー状態の場合、Apache httpdは、タイムアウトになるまでリクエストをそのサーバーに転送しません。これにより、[one]はメンテナンスのためにバックエンドサーバーをシャットダウンし、後でオンラインに戻すことができます。値0は、タイムアウトのないエラー状態のワーカーを常に再試行することを意味します。

ただし、IISバックエンドがダウンしているアプリケーションを実行しているバックエンドなど)を使用してもキャッチされない他の障害状態があります。IIS接続を確立してページを読み取ることができる場合、ページは常に500内部サーバーエラーになるだけです。ここでは、failonerrorを使用してそれをキャッチし、ワーカーを強制的にエラー状態にする必要があります。

すべての場合において、ワーカーがエラー状態になると、トラフィックはそのワーカーに転送されません。私はその最初の失敗を消費してそれを再試行するさまざまな方法を試してきましたが、エラーページがクライアントに戻るケースが常にあるようです。

12
David Newcomb

「BalancerMemberパラメータ」にプロパティ「ping」があります

ドキュメントを読むと、「ping」が500ミリ秒に設定されていると、mod_proxyがBalancerMemberに指示する前にリクエストが送信されます。 mod_proxyは、BalancerMemberからの応答を500ミリ秒待機します。mod_proxyが応答を取得しない場合、BalancerMemberはエラー状態になります。

私はこれを実装するのに疲れましたが、それはライブのBalancerMemberへのダイレクトに役立つようには見えませんでした。

<Proxy balancer://APICluster>
    BalancerMember https://api01 route=qa-api1 ttl=5 ping=500ms
    BalancerMember https://api02 route=qa-api2 ttl=5 ping=500ms
    ProxySet lbmethod=bybusyness stickysession=ROUTEID
</Proxy>

http://httpd.Apache.org/docs/2.4/mod/mod_proxy.html

Pingプロパティは、リクエストを転送する前にバックエンドへの接続を「テスト」するようにWebサーバーに指示します。 AJPの場合、mod_proxy_ajpはajp13接続でTomcat 3.3.2 +、4.1.28 +、5.0.13 +で実装されたCPINGリクエストを送信します。 HTTPの場合、mod_proxy_httpは100-Continueをバックエンドに送信します(HTTP/1.1でのみ有効-HTTP/1.1以外のバックエンドでは、このプロパティは効果がありません)。どちらの場合も、パラメーターは応答を待機する秒単位の遅延です。この機能は、ハングしてビジーなバックエンドの問題を回避するために追加されました。これにより、問題になる可能性のある通常の操作中にネットワークトラフィックが増加しますが、一部のクラスターノードがダウンしているかビジー状態の場合は、トラフィックが減少します。 msの接尾辞を追加することにより、遅延をミリ秒単位で設定することもできます。

0
DanFredell