NI+CでSoftLayerエンジニアをしている常田です。

SoftLayerでは以前より好評頂いている「ObjectStorage」がありますが、同様に「Message Queue」についてもAPI含めサービス提供しています。 今回は、数回に分けてCliやAPIを利用して簡単なMessage Queueについての動作を紹介したいと思います。

2回目の今回はトピックの機能を利用してメッセージを配信してみたいと思います。

準備

前回までの環境に加えてphpが利用できる環境を用意して下さい。
ここでは特にPHPの導入方法は記載しませんが基本的にはパッケージ(apt-getやYum)から導入している状態で問題ありません。cURLエクステンションが利用可能なっている必要があります。
slcliコマンドだけでもある程度出来ますが送信時のHeader情報などが挿入できないため少し利用できる範囲が狭くなります。

APIライブラリのダウンロード

gitに、「softlayer-message-queue-php」プロジェクトが有りますのでこちらをクローンして利用します。

git clone https://github.com/softlayer/softlayer-message-queue-php.git

今回はここのexamplesのサンプルを修正して利用して見たいと思います。
作業は examples ディレクトリ以下で実施します。これらの関数はbootstrap.phpで初期化して動作するようになっており環境変数にキーなどをセットするように記載されています。

export QUEUE_ACCOUNT=5ymxxx
export QUEUE_USERNAME=NIC396820
export QUEUE_API_KEY=*************************************

と設定した上で処理を動作させて行きます。

トピックの利用

トピックの動作

SoftLayer MessageQueue

基本的な動作としては、メッセージ・キューのトピックにメッセージが送信されると登録(Subscribe)されている受信者に向けてメッセージが送信されます。
これにより利用者は多重の送信処理についてあまり気にすることなく大量のメッセージ配信が出来るようになります。ここで送信にはHTTPプロトコルのPOSTメソッドが利用できるという事を思い出して下さい。
つまりREST APIなどで待ち受けているWebサービスに対してメッセージが配信出来るということです。
実際には再送であったりとか考慮は必要になるかもしれませんが幾つかの場面では利用できるのではないでしょうか。

今回の試験

今回は受信者として、SoftLayerで利用可能なメール配信サービス「Sendgrid」を利用してメールを配信したいと思います。SendGridの利用方法は下記のリンクを参照して下さい。

図に示すと以下の様な流れになります。

SoftLayer MessageQueue

この仕組があればトピックにメッセージを送信するだけでメールが配信されることになります。

ここでの内容は

の内容に記載されていることを検証してくことになります。リンク先にはSendgrid以外にも電話APIであるtwillioなどへの送信するサンプルが有ります。

トピックの作成

コマンドラインではheaderが付けられないので以下のPHPソースは以下のようになります。

<?php
include 'bootstrap.php';

$messaging = new SoftLayer_Messaging();
if (!$messaging->authenticate(QUEUE_ACCOUNT, QUEUE_USERNAME, QUEUE_API_KEY)) {
    echo "Unable to authenticate!" . PHP_EOL;
    exit;
}
$my_first_topic = $messaging->topic('my_first_topic')->create();

$my_first_topic->setTags(array('tag1'));
$my_first_topic->update();


$sendgrid = new SoftLayer_Messaging_Endpoint_Http();
$sendgrid->setMethod("POST");
$sendgrid->setUrl("https://sendgrid.com/api/mail.send.json");
$sendgrid->setHeaders(array("Content-Type" => "application/x-www-form-urlencoded"));
$sendgrid->setBody("to=AAAA@docomo.ne.jp&from=notice@niandc.co.jp&subject={severity}:Logger&text={body}&api_user=username&api_key=password");

$messaging->topic('my_first_topic')->subscription()
->setEndpointType('http')
->setEndpoint($sendgrid)
->create();

?>

これをslcliで確認してみましょう。

:...............:..........................................................:
:      property : value                                                    :
:...............:..........................................................:
:            id :73c8a0455354e30fb0b1d5e8987b4e4f                          :
: endpoint_type : http                                                     :
:          body : to=(略):
:    account_id : 5ymf7                                                    :
:           url : https://sendgrid.com/api/mail.send.json  
:       headers : {u'Content-Type': u'application/x-www-form-urlencoded'}
:        params :                           
:        method : POST              
:...............:..........................................................:

登録されていますね。

トピックの操作

トピックの書き込み

トピックの書き込みについても同様にslcliでも可能ですがAPIを直接利用したほうが情報が多く付けることが出来ます。

<?php
include 'bootstrap.php';

$messaging = new SoftLayer_Messaging();
if (!$messaging->authenticate(QUEUE_ACCOUNT, QUEUE_USERNAME, QUEUE_API_KEY)) {
    echo "Unable to authenticate!" . PHP_EOL;
    exit;
}
// $my_first_topic = $messaging->topic('my_first_topic')->create();
$my_first_topic = $messaging->topic('my_first_topic')->fetch();


$my_first_topic->message()
    ->addField('severity', '重要')
    ->setBody('このメールはメッセージ・キューのサービスを利用して通知されています!')
    ->create();
?>

この中のFieldで指定した内容は、SubScribeした時に{severity}として指定しています。このように送信時にある程度値を変更できます。
結果として以下の様なメールが届きました。日本語も問題なく送信出来ていることがわかります。

Slack

その他の操作

sclliやAPIでトピックについてできる事はあまりありません。キューのようにスタックされたりはしないためpushしか用意されていません。
再送的なものがあるのかまでは調べられていないのでまた今度調べてみたいと思います。

  topic-add          Create a new topic.
  topic-detail       Detail a topic.
  topic-list         List all topics on an account.
  topic-push         Push a message into a topic.
  topic-remove       Delete a topic.
  topic-subscribe    Create a subscription on a topic.
  topic-unsubscribe  Remove a subscription on a topic.

ここまでくれば凡そサブコマンドの名前から見ての通りのことが可能です。

まとめ

キューだけでなくトピックについても上手く使うことでサービスを利用して仕組みが作れますね。トピックの送信についてもREST APIで操作できますので応用ができるかと思います。
3回で簡単にメッセージ・キューの機能を見てきましたが如何でしょうか。
4回目を書くときにはキューを利用した何かしらの仕組みにについて書いてみたいと思います。