この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
よく訓練されたアップル信者、都元です。Amazon SQS及びSNSは、AWSにおけるスケーラブルでマネージド、そして格安のメッセージングサービスです。これらのプロダクトは「サービス」であり、開発サーバやローカルマシンにインストールして使うものではありません。
しかし、テストや開発目的で、ローカルで動作させたいこともあるかもしれません。ちなみにDynamoDBも同じようなサービスですが、こちらは公式にDynamoDB Local等のソリューションが存在します。
残念ながら、SQSやSNSにはこのような公式の対応がありませんが、GitHubをウロウロしていたら CMB (Cloud Message Bus)という、SQS/SNS互換実装が見つかったので、さっと試してみました。
インストール
CMB本体のインストール
まずはダウンロード。配布ページがあったので、こちらからダウンロードします。本検証では執筆時点の最新版「Version 2.2.43」を利用しました。インストール先はローカルのMac OSXです。
$ cd workdir
$ wget http://cmb-releases.s3-website-us-west-1.amazonaws.com/2.2.43/cmb-distribution-2.2.43.tar.gz
$ tar xzvf cmb-distribution-*.tar.gz
とりあえずはダウンロードして展開するだけ。cmbというディレクトリが掘られ、そこに全てのファイルが展開されます。cmb/config/cmb.propertiesが設定ファイルなので、中を覗いてみましょう。
cmb.cqs.service.url=http://localhost:6059/
cmb.cns.service.url=http://localhost:6061/
これらがローカルでのエンドポイントになります。
#
# configure email relay here, if email protocol is desired for cns, otherwise set enabled to false
#
cmb.cns.smtp.enabled=false
cmb.cns.smtp.hostname=
cmb.cns.smtp.username=
cmb.cns.smtp.password=
cmb.cns.smtp.replyAddress=
また、SNSにおいてemailやemail-jsonのsubscriptionを利用する場合、メールサーバの設定が必要です。残念ながら私の環境でさっと設定できるメールサーバを用意できなかったので、メールの配信までは本稿で検証できていません。設定出来る方はしておきましょう。
他はデフォルトのままで上手く動きました。
CassandraとRedisのインストール
CMBは裏側でCassandraとRedisを利用しています。…本格的じゃないですか。ローカル用の仮実装というイメージからはちょっと離れてしまいますねぇ、というのが本音ですが。まぁGitHub上のrepository descriptionも「A highly available, horizontally scalable queuing and notification service compatible with AWS SQS and SNS」となっていて。高可用性とスケーラビリティを謳ってます。いや、仮実装でいいからもっとライトなの探したほうがいいんすかね。
ま、いいです。とりあえずCassandraとRedisをインストールしましょう。私の環境にはまだインストールされていなかったのでhomebrewでサクッと入れました。
Cassandra
Cassandraはv2系が出ているようですが、ドキュメントに2.0のスキーマ定義がなかったので、1.2を選択。
$ brew install cassandra12
$ brew info cassandra12
cassandra12: stable 1.2.19
$ ln -sfv /usr/local/opt/cassandra12/*.plist ~/Library/LaunchAgents
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.cassandra12.plist
言われるがまま、launchctlの設定も済ませました。
$ cassandra-cli -h localhost -f cmb/schema/cassandra_1.2.schema
そして上記コマンドでスキーマの作成を行います。UUIDっぽいのがズラズラと出てくれば多分成功です。
ちなみに私は起動時にError: Could not find or load main class org.apache.cassandra.cli.CliMainというエラーにぶつかりました。その昔、cassandra-0.7.9をインストールしていたようで、環境変数CASSANDRA_HOMEがv0.7.9を指していました。ご参考に。
そしてもうひとつ。キースペースCNSが見つからん、というエラーでも落ちました。cmb/schema/cassandra_1.2.schemaを覗いてみると、先頭にdrop keyspace文が3つ並んでいます。こうすべきなのかはよくわかりませんが、この3つをコメントアウトしたら上手く動きました。
Redis
$ brew install redis
$ brew info redis
redis: stable 2.8.19 (bottled), HEAD
設定ファイル/usr/local/etc/redis.confを一部編集します。下記の3行を#でコメントアウトしましょう。
save 900 1
save 300 10
save 60 10000
そしてredis-server /usr/local/etc/redis.confコマンドでコンソール起動。
起動と設定
以上で動作環境は整いました。sudo cmb/bin/cmb.shでCMB起動です。sudoが無いと動きませんでした。なぜかは追ってません。
起動したら http://localhost:6059/webui にアクセスしてみてください。
初期ログインは、username/password共にcns_internalです。
ログインすると、ユーザの管理画面になります。アクセスキーとシークレットが見えますので控えておきましょう。
表の中のCNS(SNSのCMB実装)をクリックするとこのようにtopic管理画面になりますので、適当にトピック名を入力して作成してみます。
できました。
続いて(メールは届きませんが)subscribeしてみましょう。
簡単ですね。SNS (CNS)はこのあたりで。引き続き、CQS(SQSのCMB実装)の方も見てみましょう。
既に5つのキューがありましたが、6つ目を作ってみました。ちなみにこの表は横に長くてですね。。。
AttributeやPurgeにも対応していました。
AWS SDK for Javaから使ってみる
// CNS (SNS) の利用準備
AmazonSNS sns = new AmazonSNSClient(creds);
sns.setEndpoint("http://localhost:6061/");
// CNSにpublish
sns.publish("arn:cmb:cns:eu-west-1:424143290207:cmsample", "Hello, CNS!");
// CQS (SQS) の利用準備
AmazonSQS sqs = new AmazonSQSClient(creds);
sqs.setEndpoint("http://localhost:6059/");
// CQSにsend
SendMessageResult result = sqs.sendMessage("http://localhost:6059/424143290207/cmsamplequeue", "Hello, CQS!");
System.out.println("MessageId = " + result.getMessageId());
System.out.println("MD5OfMessageBody = " + result.getMD5OfMessageBody());
System.out.println("MD5OfMessageAttributes = " + result.getMD5OfMessageAttributes());
// CQSからread
ReceiveMessageResult receiveMessage = sqs.receiveMessage("http://localhost:6059/424143290207/cmsamplequeue");
receiveMessage.getMessages().stream().map(msg -> msg.getBody()).forEach(System.out::println);
なんてことはありませんね。setEndpointで、ローカルを指してやるだけで、動きました。
MessageId = 0:0:0_0_81:2986657831232471042:-5491847274831020032
MD5OfMessageBody = 1b51da5780bbd08ce96081f7b6ba4983
MD5OfMessageAttributes = null
Hello, CQS!
残念ながら、SNSのメッセージの受信確認はできませんでしたが、普通に受信できるものだと思います。
最後に
一応、ドキュメントに明示されていた制限事項を確認しておきましょう。
- AWS SDK for Java v1.9.14 を使って動作確認をしています。(意外と最新に近いですね)
- Cassandra 1.0.10 では動きません。1.1.X, 2.0.X, 2.1.XはOK(2.0で動くんじゃないか。。。)
- CNSはSMSプロトコルはサポートしません。
- CNSはスロットルポリシーをサポートしません。
- CNSはモバイルpushをサポートしません。
- CQNはDLQをサポートしません。
とのことです。この制限の中では便利に使えるのではないでしょうか。