CloudQueueMessage.DequeueCountの用途と使い方について
以前に記述した id:waritohutsu:20091218:1261092402 の記事では、「Windows Azure基盤側にはCloudQueueMessageのデキューされた回数は実装されているが、Windows Azure SDK にはデキューされた回数を取得できるAPIが公開されていない」と記述しましたが、Windows Azure SDK 1.1では、ついにデキューされた回数は取得できるようになりました!!
今回の記事では、CloudQueueMessage.DequeueCountの用途と使い方を紹介します。
CloudQueueMessage.DequeueCountの用途
Windows Azureのキューストレージに限らず、キューを利用した場合に検討されるのが「キューのメッセージを処理している最中に例外が発生した場合に無限ループになる」という問題です(下図参照)。
凄い手抜きなので私がへこんで来た事はさておき、以下のような問題が起きます。
- クライアント側からキューにメッセージを送り、キューにメッセージが格納される
- サーバ側がキューからメッセージを取得する
- サーバ側で取得したメッセージを処理中に例外(障害)が発生する。
- 例外を発生させたメッセージがキューに戻るが、再度同メッセージをサーバ側で取得して再び例外が発生する(以下、無限ループ)
上記の問題を解決するため、一定回数以上デキュー処理を行ったメッセージに特別な処理を行う必要があります。この「一定回数以上デキュー処理を行ったメッセージ」として判別するため、CloudQueueMessage.DequeueCountが利用できます。
CloudQueueMessage.DequeueCountの使い方(MSDNドキュメント)
Windows Azure SDK 1.0 2009 Novemberが公開された当時には駄目駄目でしたが、先ほど確認したところMSDNにCloudQueueMessage.DequeueCountが追記されています。具体的な使用例は以下となります。
//キューからメッセージを取得 CloudQueueMessage msg = queue.GetMessage(); //メッセージに格納された文字列とデキューカウントを表示 Trace.TraceInformation( "キューからDequeue={0}、デキュー回数={1}回目", msg.AsString, msg.DequeueCount); queue.DeleteMessage(msg);
CloudQueueMessage.DequeueCountの使い方(動作確認に使用するサンプルアプリケーション)
@ITで公開されている記事 「Windows Azureストレージ開発入門(後編)初めてのブロブ&キュー・ストレージ開発」で使用されているキューストレージのサンプルアプリケーションを参考にします。機能概要としては以下になりますが、Wokerロール側の処理を変更しています。
- Webロール側
- ユーザが「発言内容」をテキストボックスに入力する。
- ユーザが「キューへメッセージを発行」ボタンを押した際に、キューストレージ(myqueueキュー)へ「発言内容」を格納する。
- Workerロール側(サンプルコードと日本語が微妙に合ってないなぁという自覚はあるが、面倒で修正はあきらめた)
- 10秒に一度キューストレージ(myqueueキュー)を確認し、メッセージの内容とデキューカウントをTrace.WriteLineを出力する。
- キューストレージから取得したメッセージが5回以上デキューされている場合は、エラーメッセージを出力してキューからメッセージを削除する。
- キューストレージから取得したメッセージが「変態」を含む文字列の場合、例外メッセージを出力するが、キューからメッセージを削除しない。
また、Workerロールのキューメッセージ処理部分のサンプルコードを提示します。
//Webロール側からのメッセージを取得して表示する while (true) { try { //キューからのメッセージを取得 CloudQueueMessage msg = queue.GetMessage(); if (msg != null) { if (msg.DequeueCount >= 5 ) { //5回以上デキュー済みなので、エラーメッセージを出力後にメッセージ削除 Trace.Fail(string.Format("メッセージ{0}は5回以上デキューされましたが、処理が完了できませんでした", msg.AsString)); queue.DeleteMessage(msg); } else if (msg.AsString.Contains("変態")) { //例外が発生するので、メッセージをキューから削除しない throw new ArgumentException("変態を含むメッセージは処理できない"); } else { //メッセージを処理し、キューから削除する Trace.TraceInformation( "キューからDequeue={0}、デキュー回数={1}回目", msg.AsString, msg.DequeueCount); queue.DeleteMessage(msg); } } else { Trace.TraceInformation("キュー内のメッセージが空です = null"); } Thread.Sleep(10000); } catch (Exception ex) { Thread.Sleep(10000); Trace.TraceError(string.Format("キューの処理中に例外 '{0}'", ex.Message)); } }
CloudQueueMessage.DequeueCountの使い方(サンプルアプリケーションの動作)
サンプルアプリケーションを起動して、以下の処理を行いました。
- スタートメニューから Development Fabric UIを起動して、Workerロール側のインスタンスを選択する。
- Webロール側のテキストボックスに対して、「Shibayanは変態!って入力すると例外がでる」という文字列を入力し、「キューへメッセージを発行」ボタンを押す。
- Development Fabric UIのWorkerRole1のインスタンスが「5回以上デキューしたけど」処理できなかった旨のメッセージを出力していることを確認する。
- Webロール側のテキストボックスに対して、「割と普通は普通!って入力するとOK」という文字列を入力し、「キューへメッセージを発行」ボタンを押す。
- Development Fabric UIのWorkerRole1のインスタンスが、入力したメッセージとデキューカウントを出力していることを確認する。