Elastic MQ を使用して複数の Bluemix アプリケーションを迅速に統合する

2014年 7月 02日
PDF (439 KB)
 
Mark Phillips

Mark Phillips

MQ Cloud Technical Lead

@markphillips

Melanie Rao

Melanie Rao

MQ Cloud Software Engineer

IBM Bluemix™ にサインアップ
無償のサービス、ランタイム、インフラを含むクラウド・プラットフォームが、新たなモバイルやウェブ・アプリのクイックな構築とデプロイを実現します。

Bluemix にデプロイされたアプリケーションに対し、Elastic MQ は柔軟で使いやすいメッセージング・サービスを提供します。Elastic MQ をキューイング・サービスとして使用すれば、キューという手段によって、単一のメッセージを個々の受信者に送信することができます。あるいはパブリッシュ/サブスクライブ・ブローカーとして使用すれば、複数の受信者に通知を送信することも可能になります。このサービスは、例えば数多くの動画を処理する必要があるモバイル・アプリケーションや Web アプリケーションなどで利用することができます。こうした CPU インテンシブな処理は、Elastic MQ によってクラウド上のバックエンド・ワーカー・アプリケーションの複数のインスタンスにオフロードすることができます。そして、これらのワーカーのそれぞれが応答キューに非同期で応答することで、モバイル・アプリケーションや Web アプリケーションが応答を収集することができます。

Elastic MQ には、次の特徴があります。

  • 一般的な使用ケースの場合、管理が不要です。
  • JMS API を使用するように作成された Java アプリケーションをサポートします。
  • MQ Light API を使用するように作成された Node.js アプリケーションをサポートします。

このサービスで発生する可能性のある問題については、Bluemix 開発者コミュニティー・サイトの「Get help」ページを参照してください。

アプリケーションを作成するために必要となるもの

 

ステップ 1. Elastic MQ JMS API を導入する

 

Elastic MQ JMS API の使い方を理解できるように、まずは、サンプル・アプリケーションをデプロイする方法を簡単に説明します。このサンプル・アプリケーションは、Bluemix 上の Elastic MQ インスタンスにバインドし、ユーザーが入力した英語の文を取得して、その文に含まれる単語を大文字に変換します。

Elastic MQ が英語の文を単語に分割し、大文字の単語にして応答を送信する仕組みを示す図

このサンプルは、次の 2 つのコンポーネントからなります。

  • Java サーブレットとして実装される Web アプリケーション。この Java サーブレットは Java EE (JEE) の .war ファイルとしてパッケージ化され、WebSphere Application Server Liberty ランタイム内で実行されます。このアプリケーションは、Web ページで入力されたテキストを受け取り、そのテキストを単語に分解してから、それらの単語をワーカー・アプリケーションに送信します。そして、処理された単語を応答メッセージとして受信して、それらのメッセージをWeb ページ上にワーカー ID ストリングと併せて動的に表示します。このサーブレット Web アプリケーションによって、JEE アプリケーションを Liberty にデプロイする方法、Elastic MQ への接続を確立するために JNDI ルックアップを使用する方法、キューとの間でメッセージを送受信する方法を実演します。
  • Bluemix にデプロイされる Java SE ワーカー・アプリケーション。このアプリケーションは、ユーザーが入力した英語の文を取得し、各単語を大文字に変換してから、キューに入れます。Java JMS ワーカー・プログラムでは、Elastic MQ ヘルパー・クラスを使用して JMS アプリケーションを Elastic MQ サービス・インスタンスにバインドする方法、あるキューから要求メッセージを取得し、別のキューに応答メッセージを入れるために Elastic MQ プロトコルを使用する方法、そしてキューのメッセージを処理するために複数のワーカー・アプリケーションを使用する方法を実演します。

ステップ 2. ソース・コードをダウンロードしてコンパイルする

 

サンプルのソース・コードは、IBM DevOps Services プロジェクトに保管されています。サンプルをダウンロードしてビルドするには、GIT ファイル、ANT ファイル、および Java SDK をダウンロードする必要があります。この記事の最初のほうにある青いボタンをクリックすると、ソース・コードを入手することができます。

ソース・コードを入手し、サンプルのコンポーネントをビルドするには、以下の手順に従います。

  1. 上記のボタンがリンクしているページで指定されている GIT URL を使用して、DevOps Services から GIT リポジトリーを複製します (ヘルプを表示するには、DevOps Services の「HELP (ヘルプ)」セクションを参照してください)。
  2. 最上位レベルの mqservicesampleweb には Web アプリケーションが格納されている一方、mqservicesampleworker にはワーカー・アプリケーションが格納されています。これらのディレクトリーのそれぞれで ant を実行し、それぞれのアプリケーションに対応するバイナリーをビルドします。変更を行った後は、再び ant を実行して、更新されたバイナリーを生成します。

ステップ 3. JMS ワーカー・アプリケーションを扱う

 

以下のコードに、エラー・チェックと宣言を省いて簡素化したプログラムを示します。

Connection conn = WebSphereMQServiceConnectionHelper
    .getWebSphereMQServiceConnectionFactory()
    .getJmsConnectionFactory().createConnection();
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn.start();
Queue queue = sess.createQueue("jms/requestQueue");
MessageConsumer consumer = sess.createConsumer(queue);
while (errorCount < 10) {
     Message message = consumer.receive();
     Destination replyDestination = message.getJMSReplyTo();
     MessageProducer replyProducer = sess.createProducer(replyDestination);
     TextMessage replyMessage = sess.createTextMessage();
     msg = ((TextMessage) message).getText().toUpperCase();
     replyMessage.setText(msg + "\tProcessed by worker ID: " + ID);
     replyMessage.setJMSReplyTo(null);
     replyProducer.send(replyMessage);
     replyProducer.close();
}
sess.close();
conn.close();

最初の行を除き、このコードは典型的な JMS コンシューマー・プログラムです。最初の行では、JMS ConnectionFactory を取得するプロセスを単純化するために、ヘルパー・クラスとして提供されている WebSphereMQServiceConnectionHelper を使用しています。

Bluemix 上にデプロイして実行する

 
  1. JMS ワーカー・アプリケーションをビルドするために、mqservicesampleworker ディレクトリーで ant を実行します。これにより、MQServiceSampleWorker.jar という名前の JAR ファイルが生成されます。
  2. サンプル・アプリケーションを起動せずにプッシュします。コマンド・ラインからアプリケーションをデプロイするには、cf コマンドを使用することができます。cf コマンドを使用したことがない場合は、Bluemix クイック・スタートの説明を読んで、このコマンドの使い方を学んでください。以下のコマンドを入力します。

    リスティングを見るにはここをクリック

    cf push MQS.sample.worker -b https://github.com/cloudfoundry/java-buildpack -p MQServiceSampleWorker.jar --no-start --no-route

    このアプリケーションは、単独で使用される Java アプリケーションなので、-b オプションで Java ビルド・パックを指定します。また --no-route オプションによって、このアプリケーションには外部 HTTP アドレスを割り当てる必要がないことを指定します。ElasticMQ サービスは実行前のアプリケーションにバインドする必要があるため、--no-start オプションも含める必要があります。

  3. サービスを作成します。同じサービス・インスタンスを、このサンプルの Web アプリケーションとワーカー・アプリケーションの両方で共有します。サービスをまだ作成していない場合は、以下のコマンドを入力して作成してください。
    cf create-service ElasticMQ Default mqsampleservice

    作成済みのサービスを一覧表示するには、以下のコマンドを入力します。

    cf services
  4. このサービスを、まだ起動されていないアプリケーションにバインドします。サービスの名前は、mqsampleservice にする必要があります。以下のコマンドを入力します。
    cf bind-service MQS.sample.worker mqsampleservice
  5. アプリケーションを起動して、環境変数を更新し、以下のコマンドを入力します。
    cf start MQS.sample.worker
  6. Web アプリケーションとワーカー・アプリケーションの両方がデプロイされたら、実行する JMS ワーカー・インスタンスの数を増やしてサンプルをテストすることができます。例えば、インスタンスの数を 4 に増やすには、以下のコマンドを使用します。
    cf scale MQS.sample.worker -i 4

ステップ 4. JMS Web アプリケーションを扱う

 

この Java サーブレットは、HTML クライアントで表示される Web ページから送信された HTTP POST への応答として、バックエンド・サービスに要求メッセージを送信します。この Web ページは、サーブレットと一緒にパッケージ化されています。

サーブレットがパッケージ化されている WAR (Web Application Archive) ファイルには、アプリケーションのデプロイ先のコンテナーが提供する Web コンテンツと一緒に、デプロイメントに関する記述子が含まれています。サーブレットは、メッセージング・サービスへの接続を確立し、キューとの間でメッセージを出し入れする必要があるため、デプロイメント記述子には、リソース参照およびリソース環境参照としてキューの情報が記述されていなければなりません。

web.xml から抜粋した以下のコード・スニペットには、ConnectionFactory と、Java ローカル JNDI 空間で res-ref-name によって参照される 2 つの Queue オブジェクトが定義されています。

<resource-ref>
	<description> ConnectionFactory used to send and receive messages to and from the backend worker.
	</description>
	<res-ref-name>jms/CF1</res-ref-name>
	<res-type>javax.jms.ConnectionFactory</res-type>
	<res-auth>Container</res-auth>
	<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-env-ref>
	<resource-env-ref-name>jms/requestQueue</resource-env-ref-name>
	<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
<resource-env-ref>
	<resource-env-ref-name>jms/replyQueue</resource-env-ref-name>
	<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>

以下のコード・スニペットに、エラー・チェックと宣言を省いて簡素化したプログラムを示します。サーブレットが初期化され、コンテナー JNDI 空間に対する InitialContext が取得されることで、ローカル JNDI 空間から接続オブジェクトを参照できるようになります。

InitialContext ctx = new InitialContext();
ConnectionFactory myCf = (ConnectionFactory)ctx.lookup("java:comp/env/jms/CF1");
Queue myRequestQueue = (Queue)ctx.lookup("java:comp/env/jms/requestQueue");
Queue myReplyQueue = (Queue)ctx.lookup("java:comp/env/jms/replyQueue");

サンプル Web ページから HTTP POST リクエスト・メッセージを受信すると、2 つのステップが実行されます。最初のステップでは、サンプル Web ページに入力されたテキストに含まれる単語ごとに、要求メッセージがバックエンド・サービスに対して送信されます。このステップは、標準的な JMS パブリッシャー・プログラムと同様の方法で行われます。

	String message = (String) request.getParameter("message");
	Connection connection = myCf.createConnection();
	Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	MessageProducer producer = session.createProducer(myRequestQueue);
	connection.start();
	for (String word : messages) {
		TextMessage requestMsg = session.createTextMessage(word);
		requestMsg.setJMSReplyTo(myReplyQueue);
		producer.send(requestMsg);
	}
	producer.close();
	session.close();
	connection.close();

2 番目のステップでは、応答キューにバックエンド・ワーカーからの応答があるかどうかがチェックされます。応答がある場合、それが最初の問い合わせに対する HTTP レスポンスとして返されます。

	Connection connection = myCf.createConnection();
	connection.start();
	Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	MessageConsumer consumer = session.createConsumer(myReplyQueue);
	while ((replyMsg = (TextMessage) consumer.receive(1000)) != null) {
		replyMsgTxt.add(replyMsg.getText());
	}

	consumer.close();
	session.close();
	connection.close();

	generateReply(response, "SUCCESS!", replyMsgTxt);

Liberty サーバー・パッケージにデプロイする

 

サンプル・アプリケーションは、Liberty サーバー・ユーザー・プロファイルとしてパッケージ化された状態で用意されています。このプロファイルが Bluemix にデプロイされると、アプリケーション・ランタイムとして作成されているデフォルトの Liberty プロファイルが上書きされます。このデプロイメント手法を使用し、server.xml プロファイルを調整することで、アプリケーションをメッセージング・サービスにバインドするために必要な接続オブジェクトを作成し、それらのオブジェクトを Liberty コンテナー JNDI 空間で使用できるようになります。

以下に記載する XML スニペットで、Liberty のデフォルトの server.xml を変更して Liberty JNDI 空間にメッセージング・バインディングを提供する方法を説明します。

  1. まず、フィーチャー・マネージャーを使用して、WebSphere MQ リソース・アダプターを Liberty フィーチャーとしてインストールします。
    <feature>wmqJmsClient-1.1</feature>
  2. リソース・アダプターのアーカイブの場所を指定する変数を宣言します。
    <variable name="wmqJmsClient.rar.location"value="${shared.resource.dir}/wmq/wmq.jmsra.rar"/>

    アダプターは変数によって参照されることに注意してください。この変数は、デプロイ時に Liberty サーバーによって絶対パスに展開されます。そのため、アプリケーション VM 上での解凍先に関する情報がなくても、サーバー・パッケージ内のリソース・アダプターを配置することができます。

  3. アプリケーションの web.xml デプロイメント記述子に記述された要件に対応するメッセージング・オブジェクトを定義します。メッセージング・オブジェクトは、ConnectionFactory と 2 つの Queue オブジェクトです。
    <jmsConnectionFactory jndiName="jms/CF1" connectionManagerRef="ConMgr6">
    <properties.wmqJms
    hostName="${cloud.services.mqsampleservice.connection.host}"
    port="${cloud.services.mqsampleservice.connection.port}"
    channel="${cloud.services.mqsampleservice.connection.appChannel}"
    userName="${cloud.services.mqsampleservice.connection.username}"
    password="${cloud.services.mqsampleservice.connection.password}"  
    
    />
    </jmsConnectionFactory>
    <connectionManager id="ConMgr6" maxPoolSize="10"/>  
    
    <jmsQueue id="reqq" jndiName="jms/requestQueue">
    	<properties.wmqJms baseQueueName="jms/requestQueue"/>
    </jmsQueue>  
    
    <jmsQueue id="rpyq" jndiName="jms/replyQueue">
    	<properties.wmqJms baseQueueName="jms/replyQueue"/>
    </jmsQueue>

注目に値する興味深い点として、メッセージング・サービスに接続するための値に対し、ここでも変数を使用しています。これらの変数は事前に定義されており、Liberty は、メッセージング・サービスが環境変数 VCAP_SERVICES によって提供する値を使用して変数を拡張します。これらの変数は、以下の形をとります。

${cloud.services.<message_service_name>.connection.<variable>}

<message_service_name> は、作成されてアプリケーションにバインドされるサービスの名前と同じであることが重要です。

server.xml に追加できるすべてのオブジェクトを網羅したリストについては、Liberty のナレッジ・センターで構成ファイルの記述に関するトピックを参照してください。

Bluemix 上でデプロイして実行する

 
  1. JMS Web アプリケーションをビルドするために、mqservicesampleweb ディレクトリーで ant を実行します。これにより、MQServiceSampleWeb.war という名前の WAR ファイルが生成されます。このファイルは Liberty サーバー・パッケージ内の適切な場所 (dist/wlp/usr/servers/sampleserver/apps) に配置されます。
  2. サンプル・アプリケーションを起動せずにプッシュします。このアクションにより、アプリケーションと構成が Bluemix に登録されて、サービスをアプリケーションにバインドできるようになります。コマンド・ラインからアプリケーションをデプロイするには、cf コマンドを使用することができます。cf コマンドを使用したことがない場合は、Bluemix クイック・スタートの説明を読んで、このコマンドの使い方を学んでください。以下のコマンドを入力します。
    cf push MQS.sample.web -m 512M -p dist -n <unique hostname> --no-start

    -m オプションによって、アプリケーションで使用可能にするメモリーを 512 MB に指定します。 -m オプションは、512 MB のメモリーをアプリケーションで使用しなければならないことを指定します。-n オプションは、固有のホスト名を指定するために必要であり、Web フロントエンドにアクセスするための URL は、このオプションで指定されたホスト名を使用して作成されます。

  3. サービスを作成します。同じサービス・インスタンスを、このサンプルの Web アプリケーションとワーカー・アプリケーションの両方で共有します。サービスをまだ作成していない場合は、以下のコマンドを入力して作成してください。
    cf create-service ElasticMQ Default mqsampleservice

    作成済みのサービスを一覧表示するには、以下のコマンドを入力します。

    cf services
  4. このサービスを、まだ起動されていないアプリケーションにバインドします。サービスには、「mqsampleservice」という名前を付ける必要があるため、以下のコマンドを入力します。
    cf bind-service MQS.sample.web mqsampleservice
  5. アプリケーションを起動して環境変数を更新するために、以下のコマンドを入力します。
    cf start MQS.sample.web
  6. Web アプリケーションを表示するには、その URL をブラウザーに入力するか、Bluemix ユーザー・インターフェースからアプリケーションにアクセスします。Bluemix ユーザー・インターフェースからアプリケーションを起動する場合は、「Dashboard (ダッシュボード)」に進んで、アプリケーション名の隣に表示されているリンクをクリックします。

    以下の画像で示すサンプル・アプリケーションの Web UI には、入力ボックスが表示されています。ここに、アプリケーションに処理させたい文を入力することができます。「Submit Work (ワークを送信)」をクリックすると、HTTP POST リクエストが Java サーブレットに送信されます。文が Elastic MQ を介してワーカー・スレッドに送信されて処理されると、各単語を処理したワーカー・スレッドの ID と併せて処理結果が表示されます。

    入力ボックスを表示するサンプル・アプリケーションの Web UI を示す画像

まとめ

 

以上で作業は完了です!これで、ワーカー・アプリケーションの複数のインスタンスが、Elastic MQ メッセージング・サービスの JMS API を使用して Web フロントエンドと通信できるようになりました。すべてはクラウド上にホストされているため、このアプリケーションはどこからでも使用することができます。


関連トピック:Bluemix Developers CommunityUsing WebSphere MQ classes for JMSMQ Light

コメントの追加

注意: HTML コードは、コメント内ではサポートされません。


残り 1000 文字

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=WebSphere, Cloud computing
ArticleID=972981
ArticleTitle=Elastic MQ を使用して複数の Bluemix アプリケーションを迅速に統合する
publish-date=07022014