Windows Azureサービス バスのAMQPサポートの発表

Posted: 2013/05/29 カテゴリー: Uncategorized
タグ:, , , , , , ,

Microsoftは、過去5年間、Advanced Message Queuing Protocol (AMQP) 標準を開発するために、さまざまな企業と協力してきました。この20以上の企業グループは、Red HatやVMwareといったテクノロジー ベンダー、JPMorgan ChaseやCredit Suisseといったエンタープライズから構成されています。その目標は、異なるベンダー製品間の容易な相互運用性を実現する、メッセージングのためのオープンなワイヤ レベルのプロトコルを構築することでした。2012年10月に、標準化団体のOASISがAMQP 1.0をOASIS標準として承認したことを発表し (英語 / 日本語 (機械翻訳))、同じ日に、我々はWindows Azureサービス バスでのAMQP 1.0のプレビュー実装をリリースしました。

本日、Windows Azureサービス バスのAMQP 1.0サポートが正式リリース (GA) の機能としてリリースされたことを発表できて、嬉しく思います。これは運用環境で使用する準備ができており、企業向けのSLAによって支えられています。

相互運用可能なメッセージング

このリリースは重要です。AMQP 1.0のサポートによって、Windows Azureサービス バスを使って、(異なる言語を使って書かれ、異なるOS上で稼働する) 多様なメッセージング ライブラリを使ってアプリケーションを構築することができるようになりました。これらすべてのライブラリは、効率的なバイナリのワイヤ レベル プロトコルを使って通信できるようになりました。

AMQP 1.0は移植可能なデータ表現を定義しているので、これは、.NETプログラムからサービス バスに送信されたメッセージを、メッセージの構造や内容を何も失うことなく、JavaプログラムやPython/Ruby/PHPスクリプトから読むことができることを意味しています。Javaでは、標準のJava Message Service (JMS) APIがサポートされているので、既存のJavaアプリケーションを他のJMSプロバイダーからサービス バスに移植するのは簡単です。

最終的には、分散システムを構築し、オンプレミス/クラウド環境にわたったり、複数のクラウド プロバイダーにわたって稼働しているアプリケーションをつなぐために使える、本当に強力なミドルウェアとなります。

AMQPを使ったPub/Subソリューションの構築方法のウォークスルー

新しいメッセージングのサポートを使うのがどれだけ簡単かを示すために、Publish/Subscribeメッセージング パターンを使ってJava/Python/PHPで書かれた受信アプリにメッセージを送信する、単純な.NETコンソール アプリの作成方法をウォークスルーします。Windows Azureサービス バスは、オープンなAMQPプロトコルと既存のメッセージング フレームワークを使って、これを容易にするために必要となるPub/Subメッセージングのサポートのすべてを提供するようになりました。

1

.NET送信アプリは、(持続的なメッセージングの仲介者である) サービス バス「トピック」にメッセージを送信します。(キューに送信された各メッセージが、1つのコンシューマー アプリによって処理される) キューとは異なり、トピックは、Publish/Subscribeパターンを使った1対多の通信形式を提供します。トピックに複数のサブスクリプションを登録可能です。メッセージがトピックに送信されると、そのメッセージは、独立して処理されるように各サブスクリプションで利用可能になります。

各サブスクリプションを、トピックに送信されたメッセージのコピーを受け取る、仮想的な持続キューとして考えることができます。それから、オプションとして、サブスクリプションごとにトピックに対するフィルター規則を登録できます。これによって、どのトピック サブスクリプションが、トピックに対するメッセージのどれを受け取るかをフィルター/制限できます。これによって、極めて多数のユーザー/アプリケーションにわたって、極めて多数のメッセージを処理するためにスケールできます。

2

このシナリオのために、.NETコンソール アプリが「scottmessages」トピックにメッセージを送信するようにし、それから、(Java/Python/PHPで書かれた) 3つのアプリ リスナーがメッセージを受信/処理するように、別個のサブスクリプションを設定します。

手順1: サービス バス トピックと3つのサブスクリプションの作成

最初の手順は、Windows Azureポータルを使った、サービス バス トピックの作成です。

「scottgu-ns」名前空間に、「scottmessages」という名前のトピックを作成します。Windows Azure管理ポータルによって、これを行うのが簡単になります。「新規」ボタンをクリックし、「アプリ サービス」>「SERVICE BUS」>「トピック」>「簡易作成」オプションに進むだけです (これをプログラム的に作成したり、コマンドラインから作成したりすることもできます):

3

「scottmessages」トピックを作成したら、このトピックに進み、見慣れたWindows Azureダッシュボード監視表示を確認できます:

4

それから、このトピックに対して、(各アプリ リスナーに対して1つずつ) 3つのサブスクリプションを作成します。各アプリが書かれている言語に対応して、これらのサブスクリプションを「java」、「python」、「php」と名付けます (注: 好きなように名付けることができます。どれがどれに対応するかをより明確にするために、これらの名前を使っています)。プログラム的に、あるいは、ポータルのコマンド バーの「サブスクリプションの作成」ボタンをクリックすることで、これを行えます。これによって、作成したいサブスクリプションを名付けられるダイアログが現れます:

5

このダイアログの2番目の画面では、既定のメッセージの有効期限 (削除されるまでにキューに留まる期間)、ロックやセッションの設定といった、サブスクリプションのカスタム プロパティを設定できます:

6

OKボタンをクリックすると、このトピックに対してサブスクリプションが作成されます。それから、3つのサブスクリプションを持つために、この手順を繰り返して、さらに2つのサブスクリプションを作成できます:

7

これを行った後は、「scottmessages」トピックにメッセージが送信されるといつでも、そのメッセージは各サブスクリプションに対して持続的にキューイングされます。持続的なキューイングとは、メッセージが送信された時点で、コンシューマー アプリがアクティブにサブスクリプションをリッスンしている必要がないことを意味しています。後でサブスクリプション アプリが接続したとき処理できるように、メッセージは、サブスクリプション アプリに対して自動的にキューイングされます。これによって、極めて多数のユーザー/アプリケーションにわたって多数のメッセージの処理をスケールできる、非常に堅牢で疎結合なアプリケーション アーキテクチャが可能になります。

手順2: .NET送信アプリの作成

サービス バスのトピックとサブスクリプションを作成したので、トピックにメッセージを送信する単純な.NETプログラムを作成します。

サービス バスのAMQPサポートは、NuGet経由で取得できる、サービス バス.NETクライアント ライブラリの最新バージョンで利用可能です(http://nuget.org/packages/WindowsAzure.ServiceBus/)。バージョン2.1.0以降が必要です。これをダウンロードして.NETアプリケーションに追加するには、パッケージ マネージャー コンソールで「Install-Package WindowsAzure.ServiceBus」と入力するだけです。

次のコードは、コンソール アプリのユーザーにメッセージの入力を促す、単純な.NETコンソール アプリケーションです。それから、このアプリは、サービス バス.NET APIを使って、ユーザーが入力した各メッセージを、作成済みの「scottmessages」サービス バス トピックに送信します:

using System;
using System.Configuration;
using Microsoft.ServiceBus.Messaging;

namespace SendToScott
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"];

            TopicClient topicClient = TopicClient.CreateFromConnectionString(connectionString, "scottmessages");

            Console.WriteLine("Type messages you wish to post to the Topic:");

            while (true)
            {
                Console.Write("> ");
                string messageText = Console.ReadLine();

                topicClient.Send(new BrokeredMessage(messageText));
            }
        }
    }
}

このコードは、.NETのConnectionManagerクラスを使って、App.configファイルから構成設定を取得しています。サービス バス トピックに対する接続文字列を取得する (そして、それをコード内にハード コードするのを避ける) ために、このアプローチを使っています。これを指定するために使っているApp.configファイルは、次の通りです:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <appSettings>
    <add key="Microsoft.ServiceBus.ConnectionString"
value="Endpoint=sb://scottgu-ns.servicebus.windows.net/;SharedSecretIssuer=owner;SharedSecretValue=sSDdaewGUo3/wsaewtjhELlCi1y3SRwjFMX01tz2c/AXw=;TransportType=Amqp" />
  </appSettings>
 
</configuration>

注: トピックを選択し、ポータル下部のコマンド バーの「アクセス キー」ボタンをクリックすることで、Windows Azureポータルでサービス バス トピックの接続文字列を取得できます。.NETクライアント ライブラリがAMQPを使うように構成するために、接続文字列に「;TransportType=Amqp」を追加していることに注意してください。

コンソール アプリの実行

さて、.NETコンソール アプリを実行してみましょう。F5を押してコンソール アプリを実行すると、メッセージを入力してトピックに送信できるようになります。入力例を示します:

8

ここで入力された各メッセージは、サービス バス トピックに送信されます。そして、トピックは、処理のために設定した3つの各サブスクリプションに対して、メッセージのコピーを持続的にキューイングします。

手順3: Javaアプリ リスナーの作成

さて、サブスクリプションの1つに接続してメッセージを処理するJavaアプリを書いてみましょう。

Javaにおけるメッセージングの標準APIは、JMS (Java Message Service) です。JMSは基になるトランスポートに関して何も指定していないので、異なるJMS製品は、それぞれのメッセージング ブローカーと通信するために、内部で異なるプロトコルを使っています。基になるプロトコルとしてAMQP 1.0を使う、Apacheの標準JMSプロバイダーを使っていきます。このライブラリを使うと、Windows Azureサービス バスは、オープン標準のJMSプロバイダーになります!

http://people.apache.org/~rgodfrey/qpid-java-amqp-1-0-client-jms.htmlで、Apache AMQPプロバイダーを入手できます。このプロバイダーを使うアプリケーションをビルド/実行する際には、ディストリビューション アーカイブにある次の4つのJARファイルを、Java CLASSPATHに追加する必要があります。

  • geronimo-jms_1.1_spec-1.0.jar
  • qpid-amqp-1-0-client-[version].jar
  • qpid-amqp-1-0-client-jms-[version].jar
  • qpid-amqp-1-0-common-[version].jar

それから、サービス バス サブスクリプションに接続し、そのメッセージを処理するために、標準JMSメッセージングAPIを使う次のJavaコードを書くことができます:

// ReceiveScottsMessages.java

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class ReceiveScottsMessages implements MessageListener {
    public static void main(String[] args) {
        try {
            Hashtable<String, String> env = new Hashtable<String, String>();
            env.put(Context.INITIAL_CONTEXT_FACTORY,   
                "org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory");
            env.put(Context.PROVIDER_URL, "servicebus.properties");
            Context context = new InitialContext(env);

            ConnectionFactory cf = (ConnectionFactory) context.lookup("SBCF");
            Topic topic = (Topic) context.lookup("EntityName");
            Connection connection = cf.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            TopicSubscriber subscriber = session.createDurableSubscriber(topic, "java");
            subscriber.setMessageListener(new ReceiveScottsMessages());
            connection.start();

            System.out.println("Receiving messages. Press enter to stop.");
            System.in.read();

            System.out.println("Shutting down.");
            connection.stop();
            subscriber.close();
            session.close();
            connection.close();
        } catch (Exception e) {
            System.err.println("Caught exception. Exiting.");
            System.exit(1);
        }
    }

    @Override
    public void onMessage(Message message) {
        try {
            System.out.println("Message From Scott > " + ((TextMessage) message).getText());
        } catch (JMSException e) {
            System.err.println("Caught exception receiving message: " + e);
        }
    }
}

接続の詳細やメッセージング エンティティの論理名/物理名マッピングといったJMS「管理対象オブジェクト」を構成するために、Apache JMSプロバイダーが単純なファイル ベースのJNDIプロバイダーを使っていることに注意してください。Windows Azureサービス バス トピックへの接続文字列の詳細を埋め込むために使っているservicebus.propertiesファイルは、次の通りです:

connectionfactory.SBCF = amqps://owner:sSDdaYGUo3%2FwpewtjhELlCi1y4SSwjFGX01tz2c%2FAXw%3D@scottgu-ns.servicebus.windows.net
topic.EntityName = scottmessages

このプロパティ ファイルは、サービス バス接続文字列の構成要素を含む、「SBCF」というConnectionFactoryを定義しています。そのフォーマットは、次の通りです:

amqps://[username]:[password]@[namespace].servicebus.windows.net

このフォーマットで、[username]は発行者名に対応し、[password]は発行者キーのURLエンコードされた形式です。発行者キーを手動でURLエンコードする必要があります。http://www.w3schools.com/tags/ref_urlencode.aspに、便利なURLエンコードのユーティリティがあります。

Javaアプリの実行

このJavaアプリを実行すると、このアプリはサービス バス トピックの「Java」サブスクリプションに接続し、次の出力を生成します:

Receiving messages. Press enter to stop.
Message From Scott > Red Shirts are cool
Message From Scott > Cross-platform messaging is so simple with AMQP and Service Bus
Message From Scott > Windows Azure Rocks!

Shutting down.

.NETを使ってトピックに送信されたメッセージが、Javaアプリからシームレスに消費されていることに注意してください!

SpringやJEEといった人気の高いJavaフレームワークは、JMSを使って、異なるメッセージング システムを統合します。これらのフレームワークを使ってコンポーネントを書き、Windows Azureサービス バスで動くメッセージング システムを持ち、他の言語やフレームワークともシームレスに相互運用/統合することができるようになりました。

手順4: Python アプリ リスナーの作成

さて、別のサブスクリプションに接続してメッセージを処理するPythonアプリを書いてみましょう。Linux VMにこのPythonアプリをホストします。

Windows Azureを使って、極めて簡単にLinux VMを作成できます。ポータルで「新規」コマンドを選択し、「コンピューティング」>「仮想マシン」>「簡易作成」オプションを使って、CentOS仮想マシンを作成します:

9

VMがプロビジョニングされたら、VMにSSHして構成と設定を行えます。

Linux VMへのProtonライブラリのインストール

PythonとPHPのアプリに対しては、http://qpid.apache.org/proton/download.htmlでダウンロード可能な、ApacheのProtonクライアント ライブラリを使います。Protonライブラリは、Windows Azureサービス バスと通信するために使える、AMQP 1.0準拠のライブラリを提供しています。ProtonディストリビューションのREADMEファイルに、依存性をインストールしてProtonをビルドするために必要な手順の詳細が書かれています。Linux VMのコマンドラインを使って行った手順の概要は、次の通りです:

(1) yum構成ファイル (/etc/yum.conf) を編集し、カーネル ヘッダーへのアップデートの除外をコメント アウトします (# exclude=kernel*)。gccコンパイラをインストールするために、この手順が必要です。

(2) さまざまな前提条件のパッケージをインストールします。

>> yum install gcc cmake libuuid-devel
>> yum install openssl-devel
>> yum install swig python-devel ruby-devel php-devel java-1.6.0-openjdk
>> yum install epydoc

(3) Protonライブラリをダウンロードします。

>> wget http://ftp.jaist.ac.jp/pub/apache/qpid/proton/0.4/qpid-proton-0.4.tar.gz

(4) ディストリビューション アーカイブからProtonコードを抽出します。

>> tar -xvf qpid-proton-0.4.tar.gz

(5) READMEファイルに書かれた次の手順を使って、コードをビルド/インストールします。

READMEファイルがあるディレクトリから:
mkdir build
cd build
# インストール接頭辞を設定。システムによっては調整する必要あり。
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
# ドキュメントのビルド/インストールを行いたくない場合は、docsターゲットを削除します。
make all docs
# この手順には、root権限が必要です。
sudo make install

これらすべてを行うと、マシンにProtonがインストールされ、使う準備が完了します。Windows Azureサービス バス トピックの「python」サブスクリプションからメッセージを受け取るために書いたPythonコードは、次の通りです:

import sys
from proton import Messenger, Message

broker = "amqps://owner:sSDdaYHUo3/wpewtjhEDlCi1y6SRwjFMX01tz2c/AXw=@scottgu-ns.servicebus.windows.net"
entityName = "scottmessages/Subscriptions/python"

messenger = Messenger()
messenger.subscribe("%s/%s" % (broker, entityName))
messenger.start()

msg = Message()
while True:
  messenger.recv(10)
  while messenger.incoming:
    try:
      messenger.get(msg)
    except Exception, e:
      print e
    else:
      print "Message From Scott > %s" % msg.body

messenger.stop()
print "Done"

ここで、いくつかの注意点があります:

  • ブローカーに対する接続文字列は、amqps://[issuer-name]:[issuer-key]@[namespace].servicebus.windows.netの形式です。
  • メッセージを受け取る際のentityNameは、[topic-name]/Subscriptions/[subscription-name]の形式です。

さて、(Linux VMから) このPythinスクリプトを実行すると、AMQPを使ってWindows Azureサービス バスに接続し、.NETアプリから発行したメッセージが表示されます:

10

このアプリで本当にクールなことは、アプリがLinux VMでPythonを使って動作しており、オープンなAMQPプロトコルだけを使ってWindows Azureサービス バスのメッセージング システムと通信するオープン ソースのAMQPライブラリを活用していることです。

手順5: PHPアプリ リスナーの作成

さて、最後のトピック サブスクリプションに接続してメッセージを処理するPHPアプリを書くことで、終わりにしましょう。このPHPアプリを今使った同じLinux VMにホストし、Pythonで使ったのと同じProtonライブラリを使います。PHPからProtonを使うコードは、次の通りです:

<?php

include("proton.php");

$broker = "amqps://owner:sSDdaGGUo3/cpewtjhELlCi1y5SRwjFMX01tz2c/AXw=@scottgu-ns.servicebus.windows.net";
$entityName = "scottmessages/Subscriptions/php";

$messenger = new Messenger();
$messenger->start();
$messenger->subscribe("$broker/$entityName");

$msg = new Message();
while (true) {
  $messenger->recv(10);
  while ($messenger->incoming) {
    try {
      $messenger->get($msg);
    } catch (Exception $e) {
      print "$e\n";
      continue;
    }
    print "Message From Scott > $msg->body\n";
  }
}

$messenger->stop();
?>

そして、Linux VMのコマンドラインからこのアプリを実行した際の出力は、次の通りです:

11

まとめ

このサンプルは、オープンなAMQPプロトコルと (さまざまなコミュニティによってすでにサポートされている) 既存のAMQP 1.0ライブラリを使って、Windows Azureサービス バスに接続するのがどれだけ簡単かを示しています。

Windows Azureサービス バスの新しいAMQPサポートによって、複数システムにわたって相互運用できる強力な分散アプリケーションを構築することが、ずっと簡単になりました。ここで注目すべきクールなことは、異なる言語間でメッセージが交換される際に、どうメッセージが保持されているかという点です。今回の例ではメッセージ本体に単純な文字列を使いましたが、リストやマップといった、より複雑なメッセージ フォーマットに対しても同じです。AMQP 1.0の移植可能なデータ表現によって、これが達成可能になりました。

サービス バスのAMQP 1.0サポートに関するさらなる情報のためのリンクを、次に示します:

Windows Azureアカウントをすでにお持ちでない場合は、無料評価版に登録して、これらの機能すべてを今日から使い始めることができます。

関連情報

 

 

コメント
  1. […] Guthrie のブログ記事 (英語)  (翻訳:Sato Naoki's Blog にある Windows Azureサービス バスのAMQPサポートの発表 を参照してください。) 、またはこちらの AMQP の概要についての記事 […]

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中