Freigeben über


Windows Azure Web サイトで ARR のインスタンス アフィニティを無効化する

このポストは、11 月 19 日に投稿された Disabling ARR’s Instance Affinity in Windows Azure Web Sites の翻訳です。

編集メモ : 今回は、Windows Azure Web サイト チームでプログラム マネージャーを務める Erez Benari による記事をご紹介します。

Web サイトをスケール アウトする場合、Windows Azure Web サイトで Web サイトのインスタンスを複数個セットアップするという方法は非常に有効です。Windows Azure では IIS の拡張機能であるアプリケーション要求ルーティング処理 (ARR、英語) を有効に活用して、接続中のユーザーの割り当てをアクティブなインスタンスの間で決定します。ARR は、接続中のユーザーに特殊なクッキー (アフィニティ クッキー) を発行して追跡します。これにより、その後の要求において、各ユーザーがどのサーバー インスタンスと通信しているかを把握することが可能です。このような方法で、いったんクライアントが特定のサーバー インスタンスとの間でセッションを確立すると、セッションがアクティブな間は同一サーバーと通信し続けます。これはセッションセンシティブなアプリケーション (ステートレスなアプリケーション) では特に重要で、セッション固有のデータそれ自体が、特定のサーバーから他のサーバーへ移動することはありません。セッション データを SQL などの共有ストレージに格納するなどの方法で、サーバー間で移動するようにアプリケーションを設計することができますが、ほとんどのアプリケーションはそのようになっていません。このため、通常は各ユーザーが所定のサーバーと通信を続行できるようにします。ユーザーが他のサーバーに移動すると新しいセッションが開始され、アプリケーションが使用していたセッション データ (ショッピング カートの中身など) はすべて破棄されます。この一連のプロセスについて、以下に簡単にまとめました。

  1. クライアントが Windows Azure Web サイトの Web サイトに接続する。
  2. ARR がフロントエンドの Azure サーバーで動作し、要求を受信する。
  3. 使用可能なインスタンスの中から、要求を実行するインスタンスを ARR が決定する。
  4. ARR が選択したサーバーに要求を転送する。このとき、要求に対して ARRAffinity クッキーを生成して添付する。
  5. この ARRAffinity クッキーが保持されたまま、クライアントに応答が返される。
  6. クライアントが要求を受け取ると、後で使用できるようにクッキーを保存する (ブラウザーは、サーバーから受け取ったクッキーを保存するように設計されている)。
  7. クライアントが後続の要求を送信する場合、このクッキーが要求に含まれる。
  8. ARR が要求を受け取ると、クッキーを確認してデコードする。
  9. デコードされたクッキーには、先に使用されたインスタンスの名前が保持されている。このため、ARR は、インスタンスをプールの中から選択するのではなく、同じインスタンスにこの要求を転送する。
  10. 同じサイトから続けて要求が送信されるたびに 7 ~ 9 の処理が繰り返される。ユーザーがブラウザーを閉じるとこのプロセスは終了し、この時点でクッキーは消去される。

しかし、アフィニティを保持しないほうが望ましい場合もあります。たとえば、ユーザーがブラウザーを閉じずに接続が維持されたままになっていると、アフィニティ クッキーはブラウザーに保持され続け、ユーザーは数時間、数日間、またはさらに長い期間 (理論上は無制限)、サーバーに関連付けられたままとなります。コンピューターの電源をオンにしたままで、さらにブラウザーを開いたままにすることは (特に業務用のコンピューターでは) 珍しいことではなく、常時そのようにしているユーザーは数多くいます。実際には、これは、インスタンスに対するユーザーの割り当てのバランスが崩れる原因となります。スーパーのレジが 1 人の客に占有され、他の客がいつもより長く待たされるようなものです。

アプリケーションによって、またアプリケーションの用途によって、サーバーに関連付けられたユーザーへの対処をどれだけ丁寧に行うかは異なってくると思いますが、そうした点がそれほど (またはまったく) 重要ではなく、アフィニティを無効化して負荷分散を改善するほうがよい場合を考慮し、アフィニティを制御できる機能を導入しました。

アフィニティはアフィニティ クッキーで制御されるため、Windows Azure がクッキーを付与しないようにするだけでアフィニティを無効化できます。無効化すると、ユーザーから送信された後続の要求は「新規」のものとして処理されます。ARR は、要求を「そのユーザーの」サーバーにルーティングするのではなく、通常の負荷分散処理を適用し、最適なサーバーにルーティングします。

下の図は、アフィニティ クッキーの例です。

アフィニティを無効化する方法には、次の 2 つがあります。

  1. アプリケーションで設定する
  2. サイトの構成で設定する

アプリケーションでこの動作を制御するには、ARR にアフィニティ クッキーの削除を要求する、特殊な HTTP ヘッダーを送信するコードを作成する必要があります。このヘッダーは Arr-Disable-Session-Affinity というもので、true に設定すると、ARR はアフィニティ クッキーを削除します。アプリケーションに追加するコードは、次のようなものです。

headers.Add("Arr-Disable-Session-Affinity",   "True");

* この例は C# のものです。他の言語やプラットフォームでも、同様に簡単なコードを追加するだけです。

ほとんどの場面でアフィニティを保持しつつアプリケーションの特定のページでのみリセットする場合には、アプリケーションのコードでこれを設定する方法が適しています。そうではなく、アフィニティを完全に無効化する場合は、IIS 自身がヘッダーを直接挿入するようにして、ARR が常にクッキーを削除するように設定できます。これは、web.config の構成セクションの customHeaders で指定できます。次のコードを web.config に追加し、サイトのルートにアップロードするだけです。

ただし、web.config の構成はデリケートで、ファイルの設定を誤るとサイトが正常に動作しないようになるので、注意が必要です。これまで web.config ファイルを変更した経験がない場合は、こちらの入門ガイド (英語) をお読みください。

トラブルシューティング

上記を実装する場合の、動作の確認とトラブルシューティングについて説明します。ARR のアフィニティ クッキーは、通常、任意の Windows Azure Web サイトで実行されている Web サイトから受け取る最初の応答に含まれており、その後も、クライアントから送信される要求とサーバーから送信される応答のすべてに含まれます。これが動作していることを確認するには、HTTP のトラブルシューティングおよび診断用のさまざまなツールを使用できます。以下は、その主要なものです。

  1. Fiddler
  2. HTTPWatc
  3. Network Monitor
  4. WireShark
  5. Firebug

こちらのページ (英語) には、上記以外のツールもいくつか紹介されています。1 つめに挙げた Fiddler は、任意のブラウザーと相互に動作し、また無料で使用できるため、非常に人気の高いツールです。Fiddler をインストールすると、閲覧したページの URL がすべて記録され、各要求や応答で [Inspector] タブをクリックすると、その詳細を確認できます。たとえば、下の図の [Headers] タブには、Set-Cookie ヘッダーを使用してサーバーが送信したアフィニティ クッキーが表示されています。

Arr-Disable-Session-Affinity ヘッダーを追加してアフィニティ クッキーを無効化すると、ARR はこのクッキーを設定しません。しかし、この場合 Arr-Disable-Session-Affinity ヘッダー自体も削除されるため、処理が正常に実行されている場合は両方とも表示されません。クッキーとヘッダーの両方が表示される場合は、ヘッダーの設定方法に何か誤りがあるということです。ヘッダー名またはヘッダーの値を指定するテキストが間違っている可能性が考えられます。また、クッキーが表示されてヘッダーが表示されない場合、web.config ファイルの変更が無効であるか、ヘッダーに挿入したコードが正常に動作していない可能性があります。これは、他に関係のないヘッダーを追加することで確認できます。一般的には、ヘッダーを設定するには、コードよりも web.config を構成するほうが簡単です。疑わしい場合は、調査対象を絞り込むためにも、まずは単純化することを推奨します。

最後に、アフィニティの無効化は気軽に行うべきではないことに触れておきます。静的なコンテンツではあまり問題になることはありませんが、ユーザーが使用するサーバーが変更される場合に対処していないアプリケーションでは、アフィニティの無効化が有効ではないかもしれません。アフィニティが負荷分散の障害になっているケースでは、この新機能を活用するとよいでしょう。