« たぬきネコ | トップページ | HHKB Blue Key キタ━! »

2010年5月19日 (水)

(続)Ernie : Ruby/Erlang Hybrid BERT-RPC Server

ErlangRubyBERT-RPC ServerのRuby/Erlang実装であるErnieについて、面白そうなところなど。
インストール方法等はこちらをどうぞ。

ちなみに、BertもErnieもセサミストリートに登場するキャラクターだそうです。

Bert + Ernie

こういう遊び心、好きですヨ。


さて、Ernieを動作させるためにはconfigファイルが必要なので、下記のように作成し、config.cfgというファイル名で保存することにします。

[{module, ext},
{type, external},
{command, "ruby rpc-handler.rb"},
{count, 3}].
外部モジュールとして"ruby rpc-handler.rb"を実行し、そのプロセス数は3つ、という意味です。
従って、RPCとして動作させる(Ruby)コードはrpc-handler.rbというファイル名で保存すればイイわけですね。

サーバでコードが実行できる

RPCなので当たり前ですけど、リモートのコードをローカルから呼び出せます。 上記config.cfgファイルをリモート(サーバ側)に配置し、次にrpc-handler.rbというファイル名で下記をリモート側に保存します。
#rpc-handler.rb
require 'rubygems'
require 'ernie'
module Ext def hello(name) return "Hi, #{name}. I'm #{`hostname`.chomp}." end end
Ernie.expose(:ext, Ext)
コマンドプロンプトで以下を実行し、Ernieを起動します。
$ ernie -d -p 9999 -c config.cfg
最後にローカル(クライアント側)で下記スクリプト(client.rb)を実行します。
#client.rb
require 'rubygems'
require 'bertrpc'
service = BERTRPC::Service.new('リモートサーバ名', 9999) puts service.call.ext.hello('bar')
リモートサーバ名はDNSで解決できる名前かサーバのIPアドレスを適宜入力します。 サーバ名がfooの場合、実行結果は以下のようになります。
$ ruby client.rb 
Hi, bar. I'm foo.
このfooという名前は、リモート側で
`hostname`
を実行した結果ですので、確実にリモートでの実行結果をローカルで呼び出していることが分かります。

数値、stringや配列、ハッシュマップ、正規表現等が流せる

BERT and BERT-RPC 1.0 SpecificationによるとBERTとして流せるデータ型は下記の通り。
  • integer
  • float
  • atom
  • tuple
  • bytelist
  • list
  • binary
  • nil
  • boolean
  • time
  • regex
上の例ではhelloメソッドの戻り値がstringとしてBERTでローカルに流れていることになります。

それではlistに該当すると思われる配列をBERTで流してみます。
rpc-handler.rbに下記メソッドを追加し、Ernieを再起動します。

def list()
return [1, 2,'three',[4,5,'six'],7]
end
client.rbのRPC呼び出し部分は下記のように変更します。
p service.call.ext.list()
実行結果は下記の通り、期待通りに配列が取得できています。
$ ruby client.rb
[1, 2, "three", [4, 5, "six"], 7]
ハッシュも流せます。
def hashlist()
return {:a=>'a', :b=>1, :list=>list}
end
の結果は
{:a=>"a", :list=>[1, 2, "three", [4, 5, "six"], 7], :b=>1}
ハッシュなので順番は保持されませんが、正しい動作です。

次はtimeを流してみます。
rpc-handler.rbに下記メソッドを追加し、Ernieを再起動します。

def what_time?
Time.now
end
ローカルの
p service.call.ext.what_time?
の結果は期待通り
Sun May 16 02:21:13 +0900 2010
のようになります。

最後に、regex(正規表現)を流してみます。プロトコル上に正規表現を流すシーンがあまり思い浮かばないので、このような使い方で合っているのか分かりませんが、例えばrpc-handler.rbに下記メソッドを追加し、

def regex
return /foo(.*)baz/
end
client.rbを下記のようにします。
"foobarbaz" =~ service.call.ext.regex
puts $1
実行結果は
bar
であり、確かに/foo(.*)baz/でマッチした部分が取り出せています。

あるいは、rpc-handler.rbを

def regex(rgx)
"foobarbaz" =~ rgx
return $1
end
とし、ローカル側を
puts service.call.ext.regex(/foo(.*)baz/)
として、ローカルの正規表現をリモートに流し、その結果をstringで取得しても
bar
となります。

使い道は分かりませんが、とにかくBERTで正規表現が流せることが分かります。

無停止でハンドラを適用できる

ここまでに、rpc-handler.rbを適用するために、Ernieを何度か再起動していますが、実は無停止でハンドラを適用することができます。 gitのErnieのページのREADMEによると
reload-handlers Gracefully reload all of the external handlers
とあり、graceful reloadが使えることが分かります。

使い方は、コマンドプロンプトで下記のようにernieコマンドを実行するだけです。

$ ernie reload-handlers -p 9999
この場合、ポート9999でErnieが動作していなければ、エラーになります。

Erlangのフォールトトレランス

config.cfgファイルに{count, 3}と記載しておけば、外部モジュール(rpc-handler.rb)のプロセスが3つ立ち上がることは上で説明しました。

確かめてみます。

$ps x | grep ernie
29795 pts/0 Sl+ 0:00 /usr/local/lib/erlang/erts-5.7.4/bin/beam.smp (略) boot
30738 ? Ss 0:00 ernie handler unknown (ruby) - rpc-handle.rb - [1] waiting
30740 ? Ss 0:00 ernie handler unknown (ruby) - rpc-handle.rb - [1] waiting
30765 ? Ss 0:00 ernie handler unknown (ruby) - rpc-handle.rb - [1] waiting
プロセスID=30738, 30740, 30765でrpc-handler.rbのプロセスがそれぞれ3つ立ち上がっていることが分かります。

ここで、30738をkillし、再びプロセスを見てみます。

$ kill -KILL 30738
$ ps x | grep ernie
29795 pts/0 Sl+ 0:00 /usr/local/lib/erlang/erts-5.7.4/bin/beam.smp (略) boot
30740 ? Ss 0:00 ernie handler unknown (ruby) - rpc-handle.rb - [1] waiting
30765 ? Ss 0:00 ernie handler unknown (ruby) - rpc-handle.rb - [1] waiting
31356 ? Ss 0:00 ernie handler unknown (ruby) - rpc-handle.rb - [0] waiting
なんと、30738はkillされましたが、代わりにプロセスID=31356が自動的に起動し、3つのプロセス数を保っています。

これはErnieがErlangで実装されていることが大きく寄与しているものと思われます。
Erlangには言語仕様としてのフォールトトレランス(耐障害性)機能があり、Erlangプロセスが落ちても自動的に復旧させることができます。

開発者が「プロセスが落ちたとき」の振る舞いに(それほど)頭を悩ませなくて済むのは大きな利点だと思います。

最後に

長々とErnieの特徴を見てきましたが、BERTというマイナーなプロトコルを扱うこと、RPCという(たぶん)トレンドではないアーキテクチャを扱っていることなどから、WEB系の開発ではErnieを使用することはあまりないかもしれません。 しかし、クラウドが隆盛をきわめている昨今においては、分散処理が重要なキーワードになる可能性があり、軽量RPC(という言い方が正しいか分かりませんが)は分散処理においても威力を発揮しそうです。

耐障害性を持ち、複雑な手順を必要とせずにリモートのコードが実行できるErnie/BERT-RPCや、その他の軽量RPCは、意外に今後注目されるかもしれません。

|

« たぬきネコ | トップページ | HHKB Blue Key キタ━! »

Erlang」カテゴリの記事

Ruby」カテゴリの記事

コメント

Amiable fill someone in on and this mail helped me alot in my college assignement. Gratefulness you on your information.

投稿: WP Themes | 2010年6月14日 (月) 11:49

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/16742/48327554

この記事へのトラックバック一覧です: (続)Ernie : Ruby/Erlang Hybrid BERT-RPC Server:

« たぬきネコ | トップページ | HHKB Blue Key キタ━! »