涼風コンピュータblog

涼風 ・Rubyist, RubyやRuby on Railsに詳しくなっていきたいです

ServerEngineを動かしてみた

はじめに

Server EngineはUnicornのような強固なマルチプロセスサーバーを実装するためのフレームワークで、rubyで記述されています。ruby 1.9.3, 2.0.0で動作します。ログイベント収集ミドルウェア Fluentd v11に使用されています。

メイン機能は以下のとおりです。 https://github.com/frsyuki/serverengine#serverengine

Supervisorは設定ファイルを読み込み、Serverを起動します。Serverは作業する複数のWorkを起動します SupervisorはWorkerにpipe経由でハートビートを送り、自動リスタートさせます

他の機能:

  • ロギンングとログローテーション
  • シグナルハンドラー
  • シグナル時にスタックトレースとヒープダンプ
  • user変更, group変更 および umask変更
  • プロセス名の変更

Server Engineをインストール

Server Engineをインストールします

$ gem install serverengine

Simplest serverを実行

https://github.com/frsyuki/serverengine#simplest-server

Workerを1つ起動し、ログファイルに"Awesome work!"ログを書き込みます。デーモンで起動されますので、終了させるまでバックグラウンドで実行されます。筆者はMac 0S X 10.8.4、ruby ruby 2.0.0p0で確認しました。simple-server.rbとしてコードを保存します

$ ruby simple-server.rb

ファイルが2つ作成されますので、確認してみましょう。

$ ls
myserver.log        myserver.pid        simplest-server.rb

simple-server.rbに以下が設定されているため、ログファイルとしてmyserver.log,起動したプロセスIDをmyserver.pidに記録されます

se = ServerEngine.create(nil, MyWorker, {
  :daemonize => true,
  :log => 'myserver.log',
  :pid_path => 'myserver.pid',
})

myserver.logがログを書き出し先のファイルです。 myserver.pidが起動しているプロセスIDです

$ tail -f myserver.log 
I, [2013-12-22T21:52:32.750339 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:33.753536 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:34.754886 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:35.756227 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:36.756767 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:37.758424 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:38.759863 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:39.761215 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:40.762543 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:41.763787 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:42.765654 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:43.766261 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:44.767841 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:45.768601 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:46.769669 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:47.770607 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:48.771009 #12873]  INFO -- : Awesome work!
I, [2013-12-22T21:52:49.771709 #12873]  INFO -- : Awesome work!

1秒ごとにログが増えていることがわかります

myserver.pidファイルで起動しているプロセスIDを確認します

$ cat myserver.pid
12873

psコマンドでプロセスの生存を確認します

$ ps 12873
  PID   TT  STAT      TIME COMMAND
12873   ??  S      0:00.20 ruby simplest-server.rb

それでは、プログラムを終了してみましょう。TERMシグナルを送り、プログラムを止めます

$ kill -TERM 12873

myserver.logに@stop=trueが表示されました。これはTERMシグナルによりMyWoker#stopメソッドが呼ばれ、@stop=trueが設定され、MyWoker#runメソッドのループが終了したためです

...
I, [2013-12-22T22:46:11.712393 #13510]  INFO -- : Awesome work!
I, [2013-12-22T22:46:12.713562 #13510]  INFO -- : Awesome work!
I, [2013-12-22T22:46:13.714934 #13510]  INFO -- : Awesome work!
I, [2013-12-22T22:46:14.715912 #13510]  INFO -- : Awesome work!
I, [2013-12-22T22:46:15.717315 #13510]  INFO -- : @stop=true

psコマンドでプロセスが消えていることを確認しましょう

$ ps 12873
  PID   TT  STAT      TIME COMMAND

おわりに

今回はWorkerが1つというものすごく単純な構成をみました。Workerにデーモンで作業させて、TERMシグナルによる終了をみました。本当は、次のサーバー1つと4つのWokerのmulti-tcp-serverもやりたかったのですが、うまく動作させることができませんでした。たぶん、Workerに送信するクライアントプログラムが必要になると思います。それは次回やりたいと思います