Sooey

2011-04-03 15:15:01 +0900

Zed ShawがMongrel2の開発に利用してかなり気に入っているらしい、ZeroMQで遊んだ話。

まず、ZeroMQは、その名前からてっきりActiveMQやRabbitMQのようなメッセージキューサーバかと思っていたら、ぜんぜん違った。ZeroMQのサイトに書かれている表現を借りると、

The socket library that acts as a concurrency framework.

ということで、単体のサーバープロセスが動くようなキューサーバではなく、プロセス間通信、TCP、UDPマルチキャストなどの上でRequest/Reply、Publish/Subscribe、Push/Pullなどのモデルによる通信を簡単に実現するソケットライブラリなのであった。メリットや特徴はグニャラくんのwktk運営日記にあるØMQ(zeromq)について調査する。が詳しいのでそちらをどうぞ。

で、ZeroMQはインストールが用意で言語バインディングも充実しているということなので、とりあえずRubyで何か書いてみることにした(インストールや設定が超簡単ってのは重要ですね)。

例えば、Mac OS X SnowLeopard + Homebrewな環境の場合は、

$ brew install zeromq
$ ARCHFLAGS="-arch x86_64" gem install zmq -- --with-zmq-dir=/usr/local

こんな感じで、zmq.gemをインストールできる。

今回は、2つのプロセスをTCPで繋いでPublish/Subscribeモデルのメッセージングを行うものを書いてみた。それぞれの動きは以下のとおり。

  • Publishするプロセス
    • Amazon Web ServicesのEC2 APIにアクセスしてインスタンス一覧を取得する
    • インスタンス毎に「状態、識別子、起動日時」のメッセージを作成して送信する
    • 10秒待って繰り返す
  • Subscribeするプロセス
    • メッセージを受信する
    • インスタンスの状態がrunningの場合は「*** が起動しました」と表示する
    • インスタンスの状態がstoppedの場合は「*** が停止しました」と表示する
    • 次のメッセージを受信して繰り返す

EC2の情報をポーリングするプロセスが1ついれば、あとはそのメッセージをSubscribeするプロセスを書くだけで、EC2 APIをいちいち叩きに行かずともインスタンスの状態変化をキャッチできる、という流れ。

Publishするコードはこんな感じ(要amazon-ec2.gem)。

Subscribeするコードはこんな感じ。

それぞれを実行すると(起動順序はどちらが先でもよいのがZeroMQのいいところ)、

$ ruby zmq-publisher.rb
-> running i-fe4ac2ff 2011-04-01T07:44:02.000Z
-> stopping i-fe4ac2ff 2011-04-01T07:44:02.000Z

$ ruby zmq-subscriber.rb
i-fe4ac2ff が起動しました
i-fe4ac2ff が停止しました

EC2の状態を受信してPublishすると、Subscribeしている側でそれを受けたメッセージが表示される。

このシンプルさと使い勝手の良さはたしかに素晴らしいので、いつかプロダクションコードにも使ってみたいな。