特集
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 マーケティング」新着記事

CEOと従業員の給与差「299倍」をどう考える?
今回は、米国の労働事情における想像を超える格差について取り上げます。

日立ソリューションズが仮想イベントプラットフォームを提供開始
セミナーやショールームなどを仮想空間上に構築。

経営にSDGsを取り入れるために必要な考え方とは? 眞鍋和博氏(北九州市立大学教授)と語る【前編】
企業がSDGsを推進するために何が必要なのか。北九州市立大学の眞鍋和博教授と語り合った。