0MQ(zeromq)でメッセージングのさわりを勉強する

こんにちは、mi2yo4です。
8月ももう終わりです。最終日は残った宿題をやるべく、このエントリを書いている次第です。

pubsub

さて、今日はメッセージキューのお勉強を始めているので、それについて少し書いてみようかと思います。

まずは上に挙げたスクリーンショット。
全て同じPCでサンプルプログラム(プログラム1とプログラム2)を立ち上げています。
左上のウィンドウ上で動作しているプログラム1は5秒毎に「Hello world!」というメッセージを「発行」します。
他の3つのウィンドウ上で動作しているプログラム2はプログラム1の発行するメッセージを「購読」していて、メッセージを受信するとHello world!メッセージを表示するようになっています。

プログラム1とプログラム2は、ローカルループバックアドレス経由で繋がっていて、その二つの間をHello world!という「メッセージ」が流れている、という訳です。

0MQ(zeromq)とは

メッセージングが出来るようになるミドルウェアと解説されています。
異なるシステム(この場合PCと言っても良いですが)間でプロセス間通信のようなものを行いたい場合に重宝しそうなミドルウェアですね。

上のスクリーンショットはいわゆる、PubSub(publisher/subscriber)パターンを模したものですが、zeromqを用いて、ちょこっとスクリプトを書くだけで実現できてしまうのはかなり便利そうに思えます。

zeromqをWindowsにインストール

さて、そんな便利に見えるzeromqですが、早速開発マシンのWindowsに入れてみたいと思います。
Windowsではzeromqはバイナリとして提供されていますので、それを使った方が導入は簡単です。

こちらの一覧からダウンロードします。私はphp_zmq-1.1.2-5.3-ts-vc9-x86.zipをダウンロードしました。

ダウンロードしたファイルを解凍し、以下の二つのファイルをそれぞれの場所にコピーしました。

  • libzmq.dll→C:\Program Files (x86)\PHP
  • php_zmq.dll→C:\Program Files (x86)\PHP\ext

上記はWindows用のPHPインストーラーを使った場合のインストール先なので、PHPインストール先をC:\PHPなどにしている場合はそれぞれC:\PHPとC:\PHP\extに読み替えてください。

そしてphp.iniの最後の方に以下の記述を追加しておきます。

[PHP_ZEROMQ]
extension=php_zmq.dll

動作確認

そして、サンプルアプリ。これはここのほぼコピーですw

publisher.php

$publisher = new \ZMQSocket(new \ZMQContext(), \ZMQ::SOCKET_PUB);
$publisher->bind("tcp://127.0.0.1:5563");

while (true) {
    $publisher->send("FromPub", \ZMQ::MODE_SNDMORE);
    $publisher->send("hello world!");
    sleep(5);
}

subscriber.php

$subscriber = new \ZMQSocket(new \ZMQContext(), \ZMQ::SOCKET_SUB);
$subscriber->connect("tcp://127.0.0.1:5563");
$subscriber->setSockOpt(\ZMQ::SOCKOPT_SUBSCRIBE, "FromPub");
while (true) {
    $address = $subscriber->recv();
    $contents = $subscriber->recv();
    printf ("[%s] %s%s", $address, $contents, PHP_EOL);
}

今回はpublisher.phpを一つ、subscriber.phpを3つ立ち上げて動作確認をしてみました。
確かに5秒ごとに「hello world!」の文字が全てのsubscriber.phpで表示されますね。

今日のまとめ

さて、計4つのプロセスを立ち上げてメッセージが送受信されることを確認できました。
これだけですと、「何の役に立つの?」という疑問が出るかもしれません。

今回はローカルPCのみで動作確認を行いましたが、物理的に別のPC、サーバ間でも全く同じように動作させる事ができます。
という事は…メッセージの内容を各サーバ間で取決めしておけば、それらの間でメッセージの内容に沿って協調動作させることが可能になる、という事です。

実はあぐりログのサービスでも時期は未定ですが、この仕組みを取り入れようと思っています。
ある日突然、便利なサービスが展開できるかも…楽しみですね。

それではまた!