特集
Windows Azureストレージ開発入門(後編)

初めてのブロブ&キュー・ストレージ開発

野村総合研究所 勇 大地
2010/01/05
Page1 Page2

5. Windows Azureキュー・ストレージでの開発

キュー・ストレージの階層構造

 キュー・ストレージはロール間の非同期なメッセージ配信に用いられるストレージである。

 キュー・ストレージは、ストレージ・アカウント、キュー、メッセージの階層構造を提供する。

キュー・ストレージの階層構造

ストレージ・アカウント

 キュー・ストレージにアクセスする名前空間のうち最も上のレベルである。

キュー

 アカウント配下には複数のキューが保持できる。各キューには、名前と値の組からなるメタデータを最大8KBytesのサイズで付加できる。

メッセージ

 キュー・ストレージでは、メッセージという形式でデータを送受信する。キューに格納できるメッセージのサイズ上限は8KBytesとなっている。

 一般的なキューは先入れ先出し(以下、FIFO)のデータ・モデルであるが、キュー・ストレージでは必ずしもFIFOの振る舞いを保障していない。また、キューから取り出したメッセージは、キュー内で一時的に不可視となるが、明示的に削除処理を行わない場合はキューから削除されない。キューから削除されなかったメッセージは、一定時間(規定では30秒)後に再度キュー内に現れる。

 「November 2009 SDK」ではAPIが提供されていないが、メッセージがデキューされた回数を取得することが可能となる予定。

キュー・ストレージを利用したアプリケーションの作成手順

 以下では、キュー・ストレージを利用して、WebロールとWorkerロールで、メッセージのやり取りを行うアプリケーションを作成する。

 次の画面のように、Webロール側のWebフォーム画面でメッセージをテキストボックスに書き込み、[キューへメッセージを発行]ボタンをクリックすると、キュー・ストレージにメッセージが格納される。Workerロール側でこのメッセージの書き込みを検出して、何らかの処理を行い、キューからメッセージを削除するものとする。

キュー・ストレージを利用したアプリケーションの動作イメージ

 キュー・ストレージを利用したアプリケーションの作成手順は以下の流れとなる。

ASP.NET WebロールとWorkerロールの作成
Webロール側のフォーム画面を作成
Webロール側の処理ロジック(=キューへのメッセージの格納)を作成
Workerロール側の処理ロジック(=キューからのメッセージの取り出し)を作成

ASP.NET WebロールとWorkerロールの作成

 まず、前回の「Windows Azureクラウド・サービスのソリューションの作成手順」を参考に、新しい「Cloud Service」のプロジェクトとソリューションを(以下の例では「QueueConfirmCloudService」という名前で)作成し、ASP.NET Webロールを(以下の例では「WebRole1」という名前で)、またWorkerロール(以下の例では「WorkerRole1」という名前で)追加する。そして、それぞれのロールのプロジェクトで「Development Storageにアクセスするための基本設定」を行う。

Webロール側のフォーム画面を作成

 次に、Webロール側のWebフォーム画面(Default.aspx)を作成する。発言内容を入力するテキストボックスと、発言をキューに格納するイベントを発行するボタンを追加する。

 具体的には、次のようなコードになる(C#)。

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="WebRole1._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Windows Azureキュー・ストレージのサンプル</title>
</head>
<body>
  <form id="form1" runat="server">
  <dl>
   <dt>発言内容</dt>
   <dd>
    <asp:TextBox ID="CommentTextBox" runat="server"
    Text="内容無し" />
   </dd>
  </dl>
  <asp:Button ID="QueueMessageButton" runat="server"
   Text="キューへメッセージを発行"
   OnClick="QueueMessageButton_Click" />
  </form>
</body>
</html>
Webロールのフォーム画面のコード例(Default.aspx)

 なおVBの場合は、先頭行が、

<%@ Page Language="vb" AutoEventWireup="false"
    CodeBehind="Default.aspx.vb" Inherits="WebRole1._Default" %>

となる。

Webロール側の処理ロジック(=キューへのメッセージの格納)を作成

 次に、Webフォーム画面のコード・ビハインド・ファイル(Default.aspx.cs/Default.aspx.vb)に、Webページ上のボタンが押された際にメッセージをキューに格納する処理を作成する。具体的には、以下のようなコードになる。

using System;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace WebRole1
{

  public partial class _Default : System.Web.UI.Page
  {
    private CloudQueueClient queueStorage;

    private void CreateOnceQueue()
    {
      // 設定ファイルからストレージ・アクセスの情報を取得
      CloudStorageAccount storageAccount = _
        CloudStorageAccount.FromConfigurationSetting(
          "DataConnectionString");

      // ストレージ・アカウントの作成
      queueStorage = storageAccount.CreateCloudQueueClient();

      // キューの参照を取得
      CloudQueue queue =
        queueStorage.GetQueueReference("myqueue");

      // 同一名のキューが存在していなければ、キューを作成する
      queue.CreateIfNotExist();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
      // キューの作成
      CreateOnceQueue();
    }

    protected void QueueMessageButton_Click(object sender, EventArgs e)
    {
      // キューの作成と取得
      CreateOnceQueue();
      var queue = queueStorage.GetQueueReference("myqueue");

      // キューに格納するメッセージを作成する
      var message = new CloudQueueMessage(
        "発言内容「 " + CommentTextBox.Text + "」");

      // キューにメッセージを格納
      queue.AddMessage(message);
    }
  }
}
Imports Microsoft.WindowsAzure.StorageClient
Imports Microsoft.WindowsAzure

Partial Public Class _Default
  Inherits System.Web.UI.Page

  Private queueStorage As CloudQueueClient

  Private Sub CreateOnceQueue()

    ' 設定ファイルからストレージ・アクセスの情報を取得
    Dim storageAccount As CloudStorageAccount = _
      CloudStorageAccount.FromConfigurationSetting( _
        "DataConnectionString")

    ' ストレージ・アカウントの作成
    queueStorage = storageAccount.CreateCloudQueueClient()

    ' キューの参照を取得
    Dim queue As CloudQueue = _
      queueStorage.GetQueueReference("myqueue")

    ' 同一名のキューが存在していなければ、キューを作成する
    queue.CreateIfNotExist()

  End Sub


  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    ' キューの作成
    CreateOnceQueue()

  End Sub

  Protected Sub QueueMessageButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles QueueMessageButton.Click

    ' キューの作成と取得
    CreateOnceQueue()
    Dim queue = queueStorage.GetQueueReference("myqueue")

    ' キューに格納するメッセージを作成する
    Dim message = New CloudQueueMessage( _
      "発言内容「 " + CommentTextBox.Text + "」")

    ' キューにメッセージを格納
    queue.AddMessage(message)

  End Sub

End Class
Webロール側の処理ロジックのコード例(上:Default.aspx.cs、下:Default.aspx.vb)

 発言内容をテキストボックスに入力し、[キューへメッセージを発行]ボタンをクリックすると、Webロール側で処理が実行されてキューにメッセージが格納される。

Workerロール側の処理ロジック(=キューからのメッセージの取り出し)を作成

 最後に、Workerロール側に、Webロール側で格納されたメッセージを取り出し、メッセージの情報を表示する処理を実装する。具体的には次のコードのようになる。

using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;

namespace WorkerRole1
{
  public class WorkerRole : RoleEntryPoint
  {
    public override void Run()
    {
      // 設定ファイルからストレージ・アクセスの情報を取得
      var storageAccount =
        CloudStorageAccount.FromConfigurationSetting(
          "DataConnectionString");

      // ストレージ・アカウントの作成
      CloudQueueClient queueStorage =
        storageAccount.CreateCloudQueueClient();

      // キューの取得
      CloudQueue queue =
        queueStorage.GetQueueReference("myqueue");

      // Webロール側でキューが作成されるまでは停止
      while (queue.Exists() == false)
      {
        Thread.Sleep(2000);
      }

      // Webロール側からのメッセージを取得して表示する
      while (true)
      {
        try
        {
          // キューからのメッセージを取得
          CloudQueueMessage msg = queue.GetMessage();
          if (msg != null)
          {
            // メッセージの情報を表示
            Trace.TraceInformation(
              "キューからDequeue " + msg.AsString);

            // メッセージをキューから削除する
            // 削除しない場合、メッセージはキューに戻る
            queue.DeleteMessage(msg);
          }
          else
          {
            Trace.TraceInformation(
              "キュー内のメッセージが空です = null");
          }
          Thread.Sleep(1000);
        }
        catch (Exception ex)
        {
          Thread.Sleep(10000);
          Trace.TraceError(string.Format(
            "Exception when processing queue item. Message: '{0}'",
            ex.Message));
        }
      }
    }

    #region CloudStorageAccount構成設定パブリッシャのセットアップ
      ……省略……
    #endregion
  }
}
Imports System.Net
Imports System.Threading
Imports Microsoft.WindowsAzure
Imports Microsoft.WindowsAzure.Diagnostics
Imports Microsoft.WindowsAzure.ServiceRuntime
Imports Microsoft.WindowsAzure.StorageClient

Public Class WorkerRole
  Inherits RoleEntryPoint

  Public Overrides Sub Run()

    ' 設定ファイルからストレージ・アクセスの情報を取得
    Dim storageAccount = _
      CloudStorageAccount.FromConfigurationSetting( _
      "DataConnectionString")

    ' ストレージ・アカウントの作成
    Dim queueStorage As CloudQueueClient = _
      storageAccount.CreateCloudQueueClient()

    ' キューの取得
    Dim queue As CloudQueue = _
      queueStorage.GetQueueReference("myqueue")

    ' Webロール側でキューが作成されるまでは停止
    While (queue.Exists() = False)
      Thread.Sleep(2000)
    End While

    ' Webロール側からのメッセージを取得して表示する
    While (True)

      Try
        ' キューからのメッセージを取得
        Dim msg As CloudQueueMessage = queue.GetMessage()
        If msg IsNot Nothing Then

          ' メッセージの情報を表示
          Trace.TraceInformation( _
            "キューからDequeue " & msg.AsString)

          ' メッセージをキューから削除する
          ' 削除しない場合、メッセージはキューに戻る
          queue.DeleteMessage(msg)

        Else

          Trace.TraceInformation( _
            "キュー内のメッセージが空です = Nothing")

        End If

        Thread.Sleep(1000)

      Catch ex As Exception

        Thread.Sleep(10000)
        Trace.TraceError(String.Format( _
        "Exception when processing queue item. Message: '{0End'", _
          ex.Message))

      End Try

    End While

  End Sub

  #Region "CloudStorageAccount構成設定パブリッシャのセットアップ"
      ……省略……
  #End Region

End Class
Workerロール側の処理のコード例(上:WorkerRole.cs、下:WorkerRole.vb)

 キューからメッセージを取得した後に、CloudQueueオブジェクトのDeleteMessageメソッドを呼び出してキューからメッセージを削除していることに注目していただきたい。すでに述べたとおり、一般的なキューと異なり、Windows Azureストレージにおけるキューは明示的にメッセージを削除する必要がある(明示的にメッセージを削除しない場合、キューにメッセージが残り続ける。このため、同じメッセージに対して何度も処理が実行されてしまう)。

 以上でキュー・ストレージを利用したアプリケーションの開発は完了である。Visual Studioから[F5]キーを押してサンプル・アプリケーションを実行し、動作確認していただきたい。

Development Fabric UIを用いたアプリケーションの動作確認

 キュー・ストレージを利用したアプリケーションの動作を確認するため、[スタート]メニューから[すべてのプログラム]−[Windows Azure SDK v1.0]−[Development Fabric]を選択すると、そのDevelopment Fabricのアプリケーションが開始される。

 この状態で、Windowsタスクバーの通知領域にあるWindows Azureのアイコンを右クリックし、表示されるコンテキスト・メニューから[Show Development Fabric UI]を実行すると、Development Fabric UIが起動される。これにより、Trace.TraceInformationメソッド(=.NET標準のログ出力メソッド)で出力したメッセージの内容を確認できる。

 今回は、Development Fabric UIの起動後、画面左側のツリーからWorkerロールのインスタンスを選択し、Workerロールで出力されたログ・メッセージを確認する。

ローカル環境における開発用ファブリックのUI画面である「Development Fabric UI」を用いたログ・メッセージの確認

 キューにメッセージが格納されていない場合、CloudQueueオブジェクトのGetMessageメソッドの戻り値としてnull/Nothingが返される。一方、キューにメッセージが格納されている場合はメッセージの内容が表示されていることが確認できる。

 本稿では文字列形式のデータを格納しているが、バイト配列形式のデータを格納したメッセージも作成できる。実際にこれを行うには、Webロール側で、バイト配列を引数としたコンストラクタを用いてメッセージを生成し、バイト配列を格納したメッセージをキューに格納する。Workerロール側では、Webロールが格納したメッセージをキューから取り出し、CloudQueueMessageオブジェクトのAsBytesプロパティを用いてバイナリ・データを取得すればよい。

6. Windows Azureストレージ開発のまとめ

 本特集ではWindows Azureストレージについての概要から、テーブル、ブロブ、キューにおける実装方法と注意点について解説した。Windows Azureストレージを用いたアプリケーション開発は、従来のRDBを利用した開発とは大きく異なることが理解できたかと思う。

 すでに2010年1月1日からWindows Azureは正式リリースとなっている。2010年2月からは課金が開始されるため、残されたWindows Azureを無料で使える期間を活用して、クラウド上での開発を学んでみてはいかがだろうか。End of Article

 

 INDEX
  特集:Windows Azureストレージ開発入門(前編)
  初めてのWindows Azureテーブル・ストレージ開発
    1.Windows Azureストレージの概要
    2.Windows Azureテーブル・ストレージでの開発
 
  特集:Windows Azureストレージ開発入門(後編)
  初めてのブロブ&キュー・ストレージ開発
    3.Windows Azureブロブ・ストレージでの開発
  4.Windows Azureキュー・ストレージでの開発
Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

キャリアアップ

.NET未来展望台

未来展望台コーナースポンサーからのお知らせ


- PR -
- PR -
ソリューションFLASH

「ITmedia マーケティング」新着記事

ホンダがアイルトン・セナ登場の感動動画をリリース F1ブームが世界で再燃する背景に何が?
米国でモータースポーツの人気が再燃している。Hondaの新たな広告動画では、F1のアイコン...

だから就活生に嫌われる 採用活動における企業の残念なコミュニケーションとは?
No Companyは、就職活動において若者世代が望んでいる企業からの連絡頻度や内容、方法に...

記事閲読行動というインテントデータの活用 スマートニュースのデータクリーンルームでできること
電通と電通デジタルはスマートニュースと共同でデータクリーンルーム「SmartNews Ads Dat...