このgistは Cloud Foundry Advent Calendar 2013 の10日目の記事です。
昨日の記事で少し思わせぶりなことを書いてしまいましたが,実はここで紹介したgibsonを使って,Gorouter と Ruby Router v2 の性能比較をしようと考えていました。
作業に時間がかかることはわかっていたので,確言はできなかったのですが,案の定,時間がなくてこの体たらくです。
しょうがないので,「Gorouter と Ruby Router v2 の性能比較」を何回かに分けて記事にしようと思います。
今日はその第1回「gibsonを使ってmassregistrarを作る」です。
gibsonについては昨日説明したので細かくは書きませんが,Cloud Foundry のRouterに対して,アプリへのrouteを登録/登録解除する,Goで書かれたライブラリー/ツールです。
そもそも Cloud Foundry におけるRouterの仕事が何かということについては,詳しくは私が昔書いたこの記事やこの記事を見てほしいのですが,簡単に書くと
- DEAから定期的に送られてくる'router.register'のメッセージを受け取って保存する
- 'router.register'の中身は,大雑把に言うと {url, host, port} の組で,
- このurlに紐付けられたアプリが,
- このhost:portで待ち受けている
- ということを示している
- あるURLへのリクエストがくると,保存しておいた'router.register'の情報を使って,対応するhost:portにそのリクエストを転送する
- URLに対応するhost:portは複数あってもよく,複数ある場合はその中の一つを適当に選んで転送する
となります。
今回作ったのは,上記のDEAのフリをして,'router.register'メッセージを送るツールです。
出来上がったものはこちら。
ポイントは,
- 複数のgoroutineが,
- (プログラムを止めない限り)永続的に'router.register'を投げ続ける
ようにした点でしょうか。Cloud Foundry のRouterは,一定期間登録メッセージが来ないアプリについては,(何らかの理由で停止してしまったものとみなして)転送対象から外してしまうので,永続的に'router.register'を送り続けることが必要になります。
このファイルを,
- gibsonのリポジトリー下に
massregistrar
というディレクトリーを作って,そこにmain.goという名前で保存し, - gibsonのリポジトリー直下のディレクトリーで,
go install massregistrar
とすると,
massregistrarという実行ファイルが$GOPATH/bin
にできました。
実際に使ってみます。
まず,昨日の記事と同様,GrouterをNATS接続のみで起動しておきます。
次に,massregistrarを使って,メッセージの送信を開始します。
massregistrar -natsAddresses=192.168.14.111:4222 -natsPassword=*** -natsUsername=*** -numDea=3 -insPerDea=3
2013/12/11 07:50:11 configuring nats server: 192.168.14.111:4222
2013/12/11 07:50:11 configuring nats server: 192.168.14.111:4222
2013/12/11 07:50:11 configuring nats server: 192.168.14.111:4222
Gorouterのコンソールに,以下のようなログが流れ始めました。
{"timestamp":1386715826.047034264,"process_id":21243,"source":"router.global","log_level":"debug","message":"router.register: Received message","data":{"message":{"host":"127.0.0.1","port":30000,"uris":["u0.example.org"],"tags":null,"app":"","private_instance_id":""}}}
{"timestamp":1386715826.047286510,"process_id":21243,"source":"router.global","log_level":"debug","message":"Got router.register: &{127.0.0.1 30000 [u0.example.org] map[] }","data":null}
{"timestamp":1386715826.047403574,"process_id":21243,"source":"router.global","log_level":"debug","message":"router.register: Received message","data":{"message":{"host":"127.0.0.2","port":30000,"uris":["u0.example.org"],"tags":null,"app":"","private_instance_id":""}}}
{"timestamp":1386715826.047509193,"process_id":21243,"source":"router.global","log_level":"debug","message":"Got router.register: &{127.0.0.2 30000 [u0.example.org] map[] }","data":null}
{"timestamp":1386715826.048053741,"process_id":21243,"source":"router.global","log_level":"debug","message":"router.register: Received message","data":{"message":{"host":"127.0.0.3","port":30000,"uris":["u0.example.org"],"tags":null,"app":"","private_instance_id":""}}}
{"timestamp":1386715826.048171520,"process_id":21243,"source":"router.global","log_level":"debug","message":"Got router.register: &{127.0.0.3 30000 [u0.example.org] map[] }","data":null}
{"timestamp":1386715826.050664902,"process_id":21243,"source":"router.global","log_level":"debug","message":"router.register: Received message","data":{"message":{"host":"127.0.0.1","port":30001,"uris":["u0.example.org"],"tags":null,"app":"","private_instance_id":""}}}
{"timestamp":1386715826.050721884,"process_id":21243,"source":"router.global","log_level":"debug","message":"router.register: Received message","data":{"message":{"host":"127.0.0.2","port":30001,"uris":["u0.example.org"],"tags":null,"app":"","private_instance_id":""}}}
{"timestamp":1386715826.051173210,"process_id":21243,"source":"router.global","log_level":"debug","message":"Got router.register: &{127.0.0.2 30001 [u0.example.org] map[] }","data":null}
{"timestamp":1386715826.050794601,"process_id":21243,"source":"router.global","log_level":"debug","message":"router.register: Received message","data":{"message":{"host":"127.0.0.3","port":30001,"uris":["u0.example.org"],"tags":null,"app":"","private_instance_id":""}}}
..
うまくいっているようです。
■追記: 今気付いたのですが,さっき示したmassregistrarのコードには問題がありますね。'router.register'を送る際に毎回乱数を使っているので,登録されるrouteが一定しません。これについては,このシリーズ次回の記事(いつになるのか..)までに修正したいと思います。