Perl Hackers Hub

第24回 PSGI/Plack実践入門―Starman,Starlet,Twiggy,Plack::Middleware,Server::Starter(2)

この記事を読むのに必要な時間:およそ 4 分

Starlet─⁠─シンプルで高速なPSGIサーバ

Starlet本連載第6回を執筆した奥一穂氏が開発しているPSGI対応のWebサーバです。Prefork型で,Linuxのネットワークプログラミングのテクニックが多数盛り込まれており,高速な動作を実現しています。HTTP::Parser::XSモジュールを導入するとXSでHTTPヘッダ処理が行われるので,特に理由のない限りインストールしてください。

StarletにはStarmanと異なり専用の起動コマンドが付属しないので,plackupでサーバを起動します。

$ plackup -s Starlet \
  --max-workers 30 \
  --max-reqs-per-child 1000 \
  --min-reqs-per-child 800 \
  --max-keepalive-reqs 1 \
  -a helloworld.psgi

Starletの起動オプションで特徴的なのが,--max-reqsper-child--min-reqs-per-childです。Starmanの--max-requestsに相当する機能ですが,ワーカプロセスの入れ替わるタイミングがmaxとminの間のランダムな値に設定されます。Prefork型のWebサーバでは,アクセスが多くなるにつれ,各ワーカが処理したリクエスト数がほぼ同数になり,プロセスの終了と新しいプロセスを起動が同じタイミングに集中します。アクセスの多いサイトではサーバの負荷が上がり,サービスに影響が出ることもあります。そこでStarletではワーカが入れ替わるタイミングにランダム性を持たせるオプションがサポートされています。

Twiggy─⁠─ AnyEventベースの非同期Webサーバ

Twiggyはイベント駆動ライブラリのAnyEventを利用したWebサーバです。StarmanなどのPrefork型のサーバとは異なり,1個のプロセスで数十~数百の接続を受けることができます。PSGIの遅延レスポンス,ストリーミングレスポンスをサポートしており,サーバプッシュ型アプリケーションに向いているPSGIサーバです。

リスト3はAnyEventを利用して,次のリクエストが来るまでレスポンスを待つPSGIアプリケーションです。

リスト3 twiggy_sample.psgi

use AnyEvent;

my $cv;
my $app = sub {
  my $env = shift;
  $cv->send if $cv;
  $cv = AE::cv;

  return sub {
    my $responder = shift;
    my $writer = $responder->([200, ['Content-Type' => 'text/plain']]);
    $writer->write("Wait for the next request..\n");
    $cv->cb(sub{
      $writer->write("request has come!\n");
      $writer->close;
    });
  };
};

リスト3は次のコマンドで起動します。

$ plackup -s Twiggy -a twiggy_sample.psgi

curlなどでアクセスすると,レスポンスが途中まで行われたのち次のリクエストを待つ状態に入ります。

$ curl http://localhost:5000/
Wait for the next request..

別のターミナルから同じcurlコマンドを実行すると「request has come!」と表示され,レスポンスが完了します。このようにTwiggyとPSGIを利用することで,簡単にイベント駆動のアプリケーションも書けます。

Twiggy::Prefork─⁠─ Prefork対応Twiggy

Twiggy::Preforkは拙作のWebサーバです。その名のとおりTwiggyにPreforkの機能を付加しています。Twiggyはすべての接続を1個のプロセス内で処理するので,クライアント同士の情報のやりとりが行いやすいという特徴があります。しかし,シングルプロセスではCPUコアを複数積んだサーバの処理能力を活かしきれません。

そこで開発をしたのがTwiggy::Preforkです。ワーカプロセスが複数になることで,クライアント同士の情報の交換は難しくなりますが,CPUのパワーを利用してさらに多くの接続を扱えます。

$ placket -s Twiggy::Prefork \
  --max-reqs-per-child 500 \
  --min-reqs-per-child 400 \
  -a delay_res.psgi

Twiggy::PreforkはStarletと同様に1プロセスが処理するリクエスト数の最大と最小を指定できます。

Feersum─⁠─高速非同期サーバ

FeersumはC言語のイベント駆動ライブラリであるlibevをベースに作られているPSGI対応のWebサーバです。C/XSで作られている部分も多く非常に高速に動作します。筆者は残念ながら使ったことはありませんが,WebアプリケーションのチューニングコンテストISUCON」において,このFeersumを使い上位にランキングしたチームがいます。

2013年11月現在,実験的な機能とされていますが,FeersumはPrefork型にも対応しています。

$ plackup -s Feersum \
  --pre-fork=4 -a delay_res.psgi

PSGIサーバの選び方

CPANには多くのPSGIサーバがありますが,ほかのミドルウェアに依存せず単独でWebサーバとして動作するPSGI サーバを使うのがお勧めです。HTTP::Server::PSGI,StarmanやStarletなど単独で動作するPSGIサーバは,perlのインタプリタをインストール・管理するソフトウェアであるplenv本連載Vol.75で紹介されたCartoncpanmなどを使い,簡単にセットアップできます。またWebサーバとして起動すればブラウザで直接アクセスできるので開発やデバッグも捗ります。

表2にPSGIサーバを選ぶ際の基準をまとめました。非同期処理を必要としないアプリケーションであれば1行目「通常のアプリケーション」を,非同期処理が必要なら2行目「非同期処理が必要なアプリケーション」となります。そして,シングルプロセス内でのデータの共有が必要なら1列目「シングルプロセス」⁠そうでない場合は2列目「マルチプロセス」を選びます。多くの場合,マルチコアを持つサーバを使いますので,通常のアプリケーションの場合は自動的に右上のサーバになるでしょう。各カラムの中でどのサーバを選ぶべきかですが,実際のアプリケーションにおいてはどれも高速でそれほど差がありません。オプションの指定方法など開発者が慣れたサーバを選ぶのが良いでしょう。筆者の個人的なお勧めは,ホットデプロイ機能やプロセスごとに終了タイミングを変更できる機能を備えたStarletです。

表2 PSGIサーバの選び方

種類シングルプロセスマルチプロセス
通常のアプリケーションStarman
Starlet
非同期処理が必要なアプリケーションTwiggy
Feersum
Twiggy::Prefork
Feersum

<続きの(3)こちら。>

著者プロフィール

長野雅広(ながの まさひろ)

株式会社ミクシィ 開発部システム運用グループ アプリケーション運用チーム所属。mixiのアプリケーション運用に携わっています。Perlのカンファレンス,YAPC::Asia 2008でもmemcachedに関する発表を行いました。

URLhttp://blog.nomadscafe.jp/

コメント

コメントの記入