Windows Azure における OnStop イベントの適切な処理方法
このポストは、1 月 15 日に投稿された The Right Way to Handle Azure OnStop Events の翻訳です。
編集メモ : 今回は、Windows Azure および ASP.NET MVC チームでプログラマ兼ライターを務める Rick Anderson の投稿をご紹介します。
Web ロールでの再起動
Windows Azure で軽視されがちな問題の 1 つに、再起動の処理があります。データの損失や永続化されたデータの破損を防止しつつ迅速にシャットダウンおよび再起動を実行し、新たな要求を効率よく処理するためには、再起動を正しく処理することが重要です。Windows Azure クラウド サービスのアプリケーションは、オペレーティング システムを更新するために、おおよそ月に 2 回の頻度で再起動されます (OS の更新の詳細についてはブログ記事「OS のアップグレードに伴うロール インスタンスの再起動 (英語)」を参照してください)。アプリケーションを終了する際には RoleEnvironment.Stopping イベントが発生します。Visual Studio により作成される Web ロールの定型コードでは、OnStop メソッドはオーバーライドされません。このため、アプリケーションはシャットダウンまでのわずか数秒の間に HTTP 要求の処理を完了しなければなりません。Web ロールが保留中の要求によりビジー状態になっていた場合、これらの要求が失われる可能性もあります。OnStop メソッドをオーバーライドして Sleep を呼び出すと、Web ロールの再起動を最大で 5 分遅延させることができます。しかし、これは到底適切な処理とはいえません。Stopping イベントが発生すると、ロード バランサー (LB) は Web ロールへの要求の送信を停止します。したがって保留中の要求を処理するのに必要な時間以上に再起動を遅延してしまうと、仮想マシン (VM) は、何も有益な処理を行わないまま Sleep 内でスピンし続けることになります。このため、要求の処理が完了するまで OnStop メソッドで待機し、それからシャットダウン処理を開始するという方法が適切です。シャットダウンが早く完了すれば、VM の再起動や要求の処理も早く開始できます。このように適切な方法でシャットダウンするには、Web ロールのクラスに次のコードを追加します。
上記のコードは ASP.NET の現在の要求数を確認するものです。要求が残っている限り、OnStop メソッドは Sleep を呼び出してシャットダウンを遅延させます。現在の要求数が 0 になると OnStop が返され、シャットダウンが開始されます。Web サーバーが非常にビジーで、保留されている要求を 5 分以内で処理しきれない場合、アプリケーションは強制的にシャットダウンされます。ただし先に述べたように、Stopping イベントの発生後は、ロード バランサーから Web ロールへの要求の送信は停止されます。このため、Web ロールのサイズ (またはインスタンス数) が著しく不足している場合をのぞいて、現在の要求の処理は数秒間あれば十分に完了します。
上記のコードでは Trace データが記述されていますが、やや扱いの難しいオンデマンド転送を実行しない限り、OnStop メソッドからの Trace データは WADLogsTable には表示されません。後で、DebugView を使用してこれらの Trace イベントを確認する方法、および Web ロールの OnStart メソッドで Trace 処理を実行する方法をご紹介します。
Worker ロールでの適切な再起動
Worker ロールでは、Stopping イベントの処理方法が異なります。通常、Worker ロールではキュー メッセージの処理に Run メソッドが使用されます。この方法では 2 種類のグローバル変数が使用されます。1 つは Stopping イベントが発生したことを Run メソッドに通知するもので、もう 1 つはシャットダウンを安全に開始できることを OnStop メソッドに通知するものです (シャットダウンは OnStop が返されると開始されます)。下記のコードは、この 2 つのグローバル変数を使用するアプローチの例です。
OnStop が呼び出されると、グローバル変数の onStopCalled が true に設定されます。キュー イベントが処理中でない場合、これを合図として、Run メソッドのコードがループの起点でシャットダウンを実行します。
OnStop の Trace データの表示
前述のとおり、難しいオンデマンド転送を実行しない限り、OnStop メソッドからの Trace データは WADLogsTable には表示されません。この Trace イベントの表示には DebugView を使用します。ソリューション エクスプローラーでクラウド プロジェクトを右クリックし、 [Publish] を選択します。
発行プロファイルをダウンロードし、 [Publish Windows Azure Application] ダイアログ ボックスで [Debug] と [Enable Remote Desktop for all roles] を選択します。
コンパイラはリリース ビルドから Trace 呼び出しを削除するため、ビルド構成を Debug に設定して、Trace データを確認できるようにする必要があります。アプリケーションを発行した後、そのアプリケーションを実行して、Visual Studio で [Server Explorer] (Ctl+Alt+S) を選択します。さらに [Windows Azure Compute] を選択して、目的のクラウドを選択します (ここでは、運用環境である t6 を選択します)。Web ロールのインスタンスを右クリックし、 [Connect using Remote Desktop] を選択します。
リモート デスクトップ接続 (RDC) は、ユーザーが指定したアカウント名を発行ウィザードで使用し、ユーザーが指定したパスワードの入力を要求します。タスク バーの左側に表示されている [Server Manager] のアイコンを選択します。
[Server Manager] の左側のタブで [Local Server] を選択して、 [IE Enhanced Security Configuration] (IE ESC) を選択します。[IE ESC] ダイアログ ボックスのラジオ ボタンをオフにします。
Internet Explorer を起動し、DebugView をダウンロードしてインストールします。DebugView を起動し、 [Capture] メニューで [Capture Global Win32] を選択します。
フィルターのアイコンを選択し、除外フィルターを下記のように入力します。
このテストでは、RoleEnvironment.RequestRecycle メソッドを About アクション メソッドに追加しました。これは、その名のとおりシャットダウンおよび再起動のシーケンスを開始するメソッドです。代わりにアプリケーションを再発行して、シャットダウンおよび再起動のシーケンスを開始することもできます。
同じ手順で、Worker ロールの VM 内にある Trace データを確認できます。Worker ロールのインスタンスを右クリックし、 [Connect using Remote Desktop] を選択します。
先ほどと同じ手順に従って [IE Enhanced Security Configuration] を無効にします。さらに、同様に DebugView をインストールし、構成を行います。ここでは、Worker ロールで次のフィルターを使用します。
この例では Azure のパッケージを発行して、シャットダウンと再起動の処理が開始されるようにしました。
最後に 1 つ。Trace 処理を Web ロールの OnStart メソッドで実行するには、次のコードを追加します。
Trace データを OnStop メソッドから WADLogsTable に表示する方法をブログで扱ってほしいというご要望がありましたら、お知らせください。今回ご紹介した情報の大部分は、先週 Tom と私で執筆した Azure の多層アプリケーションに関するチュートリアル (英語) に基づくものです。他にも役立つヒントを多数掲載していますので、ぜひご覧ください。
--Rick@RickAndMSFT