Server::Starter、Starman、Starletを使ったオレオレ運用方法
インターネットからリクエストを直接受け付けるのはApacheやnginxで、そこからリバースプロキシでPSGIアプリを使ってレスポンスを返しているというケースを想定して書いてます。 やり方は色々とあるんだろうけれど、apachectlライクにstart,stop,restartでお手軽に運用したいのでstart_serverスクリプト(Server::Starter)をラッピングしたものを書きました。
使い方は下記の通りです。
usage: /path/to/script/appctl --stage=[development|production] [--start|--stop|--restart]
githubのソースはこちらで、以下はappctlスクリプトのソースです。ログのリダイレクトや、starman, starletの個別のオプションは直に変えてください。
#!/home/kw/perl5/perlbrew/perls/perl-5.14.3/bin/perl use strict; use warnings; use Getopt::Long; use Data::Dumper; my $stage = 'development'; my $start; my $stop; my $restart; GetOptions( 'stage=s' => \$stage, 'start' => \$start, 'stop' => \$stop, 'restart' => \$restart ) or usage(); unless ( $stage =~ /development|production/ ) { usage(); exit; } my $nohup = "/usr/bin/nohup"; my $start_server = "/home/kw/perl5/perlbrew/perls/perl-5.14.3/bin/start_server"; my $plackup = "/home/kw/perl5/perlbrew/perls/perl-5.14.3/bin/plackup"; my $server = 'Starlet'; my $app = "/home/kw/git_works/unko/server_starter/myapp.pl"; my $port = 3000; my $pid_file = "/home/kw/tmp_app/app01.pid"; my $status_file = "/home/kw/tmp_app/app01.status"; # print Dumper $stage # print Dumper $start; # print Dumper $stop; # print Dumper $restart; if ($start) { unless ( -e $pid_file && -e $status_file ) { my $cmd = "$nohup $start_server " . "--pid-file=$pid_file " . "--status-file=$status_file " . "--port=$port " . " -- $plackup -E $stage -s $server " . "--max-workers=5 " . "--max-reqs-per-child=1000 " . " $app & "; warn $cmd; system($cmd); } else { warn "server is already running.."; exit; } } elsif ($stop) { if ( -e $pid_file && -e $status_file ) { my $cmd = "/bin/cat $pid_file | xargs kill -TERM "; warn $cmd; system($cmd); } else { warn "pid_file and status_file is NOT exists.."; exit; } } elsif ($restart) { if ( -e $pid_file && -e $status_file ) { my $cmd = "$nohup $start_server " . "--pid-file=$pid_file " . "--status-file=$status_file " . "--restart "; warn $cmd; system($cmd); } else { warn "server is not running.."; exit; } } else { usage(); } exit; ############## ## functions sub usage { print << " EOT"; usage: /path/to/script/appctl --stage=[development|production] [--start|--stop|--restart] EOT exit; }
以下は調査したメモです。
=================================================================== Server::Starter(0.12)に関して ・hot deployを簡単に実行できるようにしたツール ・apachectlのrestartはstop, startの実行。gracefulは、今現在処理中の リクエストを処理しきってからstop, start。 ・hot deployは、stopとstartの間の切れ目がないように継続してリクエストを 処理できるような仕組み。(通常、サーバーをrestartする時はstopしてから startとなるので、stopしてからstartする間のリクエストは処理できない 期間が発生する。) ・メモリ上に大きなデータを乗せてサーバを動かしたい場合など、再起動に 大きな時間が必要となる時にhot deployが役にたつ。 ・Server::Starterをインストールするとstart_serverというデーモンを起動する プログラムがインストールされるので、これを使ってサーバアプリを起動する。 ・「Server::Starterから学ぶhot deployの仕組み」が比較的わかりやすい。 http://shibayu36.hatenablog.com/entry/2012/05/07/201556 使い方 start_server --port=80 -- plackup -s Starlet your-app.psgi オプション --port=(port|host:port) ポートの指定 --path=path unix socketを使った場合のパス --interval=seconds サーバーを再起動する時の最小インターバル(default:1) --signal-on-term=Signal start_serverがSIGTERMを受け取った時に起動しているサーバープログラムに 送られるシグナル。(default: SIGTERM) --pid-file=filename このオプションがセットされた場合、start_serverのプロセスIDが ファイルに記述される --status-file=filename このオプションがセットされた場合、サーバープロセスのステータスを 記述します。 --restart サーバをhot deployするためのコマンド。 start_serverのプロセスIDを--pid-fileから読み込んでSIGHUPを送ります。 --status-fileをチェックしてdeploy前のサーバがdieするまでwaitします。 --help --version =================================================================== Starlet(0.18)に関して ・HTTP/1.0 serverでkeep-aliveをサポート ・リバースプロキシの裏で動くHTTPサーバに適している(DESCRIPTIONより) ・Parallel::Preforkを使ったPreForkサーバ, graceful shutdownが可能 ・Server::Starterを使ってhot deployが可能 ・HTTP::Parser::XSを使って高速化 オプション --max-workers=# ワーカープロセスの数(default:10) --timeout=# タイムアウト設定(default:10) --keepalive-timeout=# keepaliveの継続秒数(deafult:2) --max-keepalive-reqs=# 1つのkeepaliveコネクションで返すことのできるリクエストの数。 1に設定された場合、keepaliveはoffとなる(default:1) --max-reqs-per-child=# worker processごとの処理するリクエスト数(default:100) --min-reqs-per-childe=# 設定するとmax-reqs-per-childeで設定された数との間で、worker process ごとの処理するリクエスト数がランダムかされる。(default:none) (ワーカープロセスの終了時期をずらしてforkの負荷を集中させない) http://blog.kazuhooku.com/2011/04/web-serverstarter-parallelprefork.html --spawn-interval=# 間隔をあけてワーカープロセスの再起動をするにための設定。(default:none) slow-restartのための仕掛け