便利なアクターフレームワークAkka*1でもZeroMQが使えるようなので、ネットに散らばっている情報を組み合わせながら実装してみた。一筋縄ではいかなかったので、自分がつまづいた箇所などを後学のためにメモしておこうと思う。Akka ZeroMQ Extensionに関する情報が少ないこと、そしてZeroMQ自体のインストラクションが少ないと感じたので、これからAkka ZeroMQ Extensionを使おうと考えている人の助けになれば幸いである。
ZeroMQとは
簡潔に説明すると、ZeroMQはBSDソケット風に扱うことのできるメッセージングフレームワークであり、ソケット等の低レイヤーの処理を隠蔽し、抽象化されたプロセス間メッセージングを提供する。また、ØMQ(zeromq)について調査する。により詳しい説明が存在するので、ZeroMQ自体についてより知りたい方はそちらを参照するとよい。要するに面倒なことをせずにネットワークプログラミングができるフレームワーク。しかも商用で使える(LGPL)ので勝手が良く、そこそこ高速に動作する。
インストール
Akka ZeroMQ Extension自体にZeroMQの実装は含まれないので、開発を始める前にユーザが自分でZeroMQネイティブライブラリをインストールする必要がある。説明はLinuxを前提として行う。
まずZeroMQ公式サイトからソースコードをインストールする。からzeromq-2.2.0.tar.gz
をダウンロードする。ZeroMQ 2.2.0は既に古いバージョンだ*2が、Akka ZeroMQ ExtensionがZeroMQ 2までしかサポートしていないため、敢えてこのバージョンをインストールする。
$ wget http://download.zeromq.org/zeromq-2.2.0.tar.gz $ tar zxvf zeromq-2.2.0.tar.gz $ cd zeromq-2.2.0 $ ./configure $ make $ sudo make install
Akka ZeroMQ Extensionはライブラリを/lib/
や/lib64/
で捜しているようなのでシンボリックリンクを作成する。
$ sudo ln -s /usr/local/lib64/libzmq.so /lib64/libzmq.so # 環境によってはlib64をlibに置換する
これでインストールは完了。
実装
ここでは、ZeroMQにおける基本的なメッセージングパターンであるPub-Subパターンを例として実装する。
実装自体はとてもシンプルなのでほぼ説明の必要が無いが、ひとまず全コードを貼る。
おおまかな流れは以下の通り。
- ZeroMQ Extensionを使用するために
akka-actor
とは別に別途依存性の記述をする(akka-zeromq
) - ZeroMQ用ソケットアクターを作成し、必要があれば
Listener
にメッセージハンドラとなるアクターを指定するnewPubSocket
やnewSubSocket
はnewSocket
のシュガーシンタックスであり、ソケットタイプ(PubだとかSubだとかRepだとか)の指定を省略している
- ZeroMQ用ソケットアクターに各種のメタメッセージを投げることでZeroMQの設定を行う
- Pub側では
Bind
オプションを用いてTCPソケットにバインドしている - Sub側では
Connect
オプションを用いてPub側に接続している - Sub側は
Subscribe
メッセージによりtopicping
をsubscribeしている
- Pub側では
- Pub側からZeroMQ用ソケットアクターに
ZMQMessage
を投げるとSub側に同じ物が届く。メッセージはListenerが処理するZMQMessage
には複数のByteString
をSeq
で含めることができる- Pub-Subパターンでは一つ目のフレーム((
ZMQMessage
中のByteString
のこと))はtopicの指定に使う collection.immutable.Seq
をimport
しないと動かない謎がある
- Pub-Subパターンでは一つ目のフレーム((
- Sub側の
Listener
は受け取ったメッセージを表示するだけ - Pub側では
system.scheduler.schedule
を利用して定期的にメッセージを送信させている
- 片方が切断して再接続しても何事も無かったかのように振る舞う
- 再接続も隠蔽されている
- Client(Sub)を先に起動させ、後からServer(Pub)を起動させても正常に動く。これはBSDソケットでは不可能
まとめ
- 資料が少ない
- そもそもAkka関連技術は資料が少ない
- そもそもScala(ry
- ZeroMQはNATを越えられるのでRemote actorの強化版として使えそう
- ActorとZeroMQは相性が良い(素直に書けたしコツが分かればすぐ動いた)
- 次回はReq-Repパターンやります(本当はこっちがやりたかったし必要だった)
*1:Akkaの詳しい説明は並行処理初心者のためのAkka入門を参照
*2:最新版ではZeroMQ 4が存在するようだ