Lambdaカクテル

ウェブアプリケーションエンジニアです.玉石混淆です.

ScalaでAkka ZeroMQ Extensionを使う(インストール、Pub-Sub篇)

便利なアクターフレームワーク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パターンを例として実装する。

実装自体はとてもシンプルなのでほぼ説明の必要が無いが、ひとまず全コードを貼る。

gist.github.com

おおまかな流れは以下の通り。

  1. ZeroMQ Extensionを使用するためにakka-actorとは別に別途依存性の記述をする(akka-zeromq
  2. ZeroMQ用ソケットアクターを作成し、必要があればListenerにメッセージハンドラとなるアクターを指定する
    • newPubSocketnewSubSocketnewSocketのシュガーシンタックスであり、ソケットタイプ(PubだとかSubだとかRepだとか)の指定を省略している
  3. ZeroMQ用ソケットアクターに各種のメタメッセージを投げることでZeroMQの設定を行う
    • Pub側ではBindオプションを用いてTCPソケットにバインドしている
    • Sub側ではConnectオプションを用いてPub側に接続している
    • Sub側はSubscribeメッセージによりtopicpingをsubscribeしている
  4. Pub側からZeroMQ用ソケットアクターにZMQMessageを投げるとSub側に同じ物が届く。メッセージはListenerが処理する
    • ZMQMessageには複数ByteStringSeqで含めることができる
      • Pub-Subパターンでは一つ目のフレーム((ZMQMessage中のByteStringのこと))はtopicの指定に使う
      • collection.immutable.Seqimportしないと動かない謎がある
    • Sub側のListenerは受け取ったメッセージを表示するだけ
    • Pub側ではsystem.scheduler.scheduleを利用して定期的にメッセージを送信させている
  5. 片方が切断して再接続しても何事も無かったかのように振る舞う
    • 再接続も隠蔽されている
    • Client(Sub)を先に起動させ、後からServer(Pub)を起動させても正常に動く。これはBSDソケットでは不可能

まとめ

  • 資料が少ない
  • そもそもAkka関連技術は資料が少ない
  • そもそもScala(ry
  • ZeroMQはNATを越えられるのでRemote actorの強化版として使えそう
  • ActorとZeroMQは相性が良い(素直に書けたしコツが分かればすぐ動いた)
  • 次回はReq-Repパターンやります(本当はこっちがやりたかったし必要だった)

*1:Akkaの詳しい説明は並行処理初心者のためのAkka入門を参照

*2:最新版ではZeroMQ 4が存在するようだ