YAPC::Asia 2009で、宮川さん(miyagawaさん)と松野さん(tokuhiromさん)の夢の共演「PSGI - Perl Server Gateway Interface」を拝聴しました。
詳しいレポートは技評の記事などを参照していただくとして(下記参照)、
WAF開発者でない、つまりWAFユーザー(Webアプリケーション開発者)である私の感想を記しておきます。この記事の題名は意味不明で恐縮ですが、それぞれの熟語を以下の文中で使っていることに由来するものです。
なお、GitHubでスライドも公開されました。
追記 : id:antipopさんによるPSGI/Plack勉強会という記事が公開されました。実装周りが綺麗にまとめられた素晴らしい記事です。是非ご覧ください。
追記 : PSGI/Plackサイトが立ち上がりました。
- PSGI/Plackとは
- 仕組みの詳細
HTTP::Engineと何が違うのかHTTP::Engineは停止、ただし後方互換性は維持- PSGI/Plackの今後
- エンドユーザーへの恩恵
- 全体を通して
1. PSGI/Plackとは
何かの拍子にこの場末ドメインのブログにお越しになる方は、PSGIとPlackのことは既にご存じのことと思いますが、一応簡単に振り返っておきます。
PSGI(Perl Server Gateway Interface)というのは、RubyのRackやPythonのWSGIにあたる、WebサーバーとWebアプリケーションフレームワーク(WAF)とを仲立ちするプロトコルです。GitHubにあります。Webサーバー側のインターフェース実装(FCGI, mod_perl, CGI, ...)とWebアプリケーションやWAFの結節点となるFacadeのようなものであり、これによってWAF毎にインターフェース実装を行わなくて済むようになり、壮大なDRY(Don't Repeat Yourself)が達成されるという具合です。
一方でPlackというのは、そのPSGI仕様のリファレンス実装です。議論の土台となることや、その他のWAFやWAF用フレームワークのサンプルとなることが想定されています。これもGitHubにあります。
委細は宮川さんのブログ記事PSGI - Perl WSGIや、松野さんのブログでPSGI絡みの記事群などをご覧いただくのが良いでしょう。
PSGIは仕様、Plackは実装。これが肝要です。
この両者を是非混同しないで欲しいというのは、PSGI/Plackに関わる方々の強い思いで、トークでも何度も強調されていました。
なお、この記事では仕様と実装をまとめて表現する際にPSGI/Plackなどと書いていますが、これはGNU/Linuxのアナロジーとしての書きぶりであって、(恐らく)正式なものではありませんのでお気をつけください。
2. 仕組みの詳細
2.1. リクエスト
リクエストはハッシュリファレンスです。キーと値については、多くはCGIでの環境変数%ENVがそのまま使われる感じです(SERVER_NAME, SERVER_PORT, PATH_INFO, QUERY_STRING, ...)。そのほかには、psgi.versionというPSGI自体のバージョンを示す値など、PSGI独自の値が付加されます。
注目したいのはpsgi.multithreadやpsgi.multiprocess等々というキーです。Webアプリケーションがマルチプロセスで稼働しているのか、1プロセスでブロッキングしながら稼働しているのか、CGIのように都度都度プロセスが生成・破棄されるのか、ということを分かるようになって嬉しいです。そういう(機械に近いという意味の)低水準の内容も面倒を見てくれます。
2.2. レスポンス
レスポンスは配列リファレンスです。
[
200,
[
'Content-Type' => 'text/html',
# ...
],
[
"Hello, World"
]
]
0番目はHTTPレスポンスコードです。
1番目はHTTPレスポンスヘッダです。何故ハッシュリファレンスでないかというと、同じキーで複数の値を持つことが有り得るためです(Set-Cookieなど)。レスポンスヘッダという、最終的には文字列で表現するしかない値について、多重データ構造を持ち出すのは確かに変な話ですしね。
そして2番目が実際のレスポンスの中身です。グロブやコードリファレンスを使うことも出来ます。
「ハッシュリファレンスでなく配列リファレンスで面倒臭い」と思うのは間違いで、それはWAF(のアダプター)がやってくれるのでどうか安心して欲しい、とのことでした。
2.3. Perl5での最適解
宮川さんは、Iteratorなどが(Rubyなどと違って言語組み込みとしては)存在しないPerl5の言語仕様に沿う形で、PSGIを妥協して低水準(機械に近いという意味)なものにしたと仰いました。セクシーな作りはひとまず諦めたという類のことを仰ったように、至って単純明快な仕組みです。
HTTP::Engineの場合にはHTTP::RequestとHTTP::Responseを扱っていましたが、PSGIでは素のリファレンスを取り扱います。勿論、WAF側でそれらのオブジェクトを触りたいという要求を妨げる物ではないので、使いたければPSGI/PlackのWAF側アダプターでそれらのオブジェクトを作れば良いのです。
これらの仕組みは、本質となる汎用部分はなるべく薄く小さくするという理念に叶った、とても現実的な解だと思いました。Perlの性格は、Perl6を考慮の外に置くならば「エレガントでセクシーな設計も良いだろう。ただ、エレガントでセクシーに動くのならば、それでいいじゃないか、中身がどんな風になっていたって」というようなものだと私は感じていますので、(良い意味で)とてもPerl的な動きだと思います。
3. HTTP::Engineと何が違うのか
3.1. 仕様と実装とアダプターが密結合されていたHTTP::Engine
CatalystやJiftyやその他多くのWAFでそれぞれ同じようなことを書かなければいけない現状をやめて、統一されたAPIを使おうということが、HTTP::Engineの出発点でした。
整理しておくと、HTTP::Engineには以下の3要素が混在していました。
- WebサーバーとWebアプリケーションの仲立ちとなる仕様
- 上記1.のAPI実装
- Webサーバー側の各種インターフェース実装(FCGI, CGI, mod_perl, ...)毎のHTTPリクエストを解釈する実装
しかしHTTP::Engineはその他にも「(場合によっては)余計なこと」を色々と実行しているので、既存のWAFの当該部分を置き換えるのは難しかったようです。細かいところでは、私はMouse(とAny::Moose)が好きなのですが、そうでない人もいらっしゃるようで、HTTP::EngineがAny::Mooseを使っていることで食わず嫌いされてしまうこともあったようです。
3.2. 分解と再配置
上記の各要素を部品に分解して、
- 仕様はPSGIへ
- 仕様のリファレンス実装はPlackへ
- サーバーのインターフェース実装への対応は
PlackのアダプターであるPlack::Impl::*へ
というようにそれぞれ分担させたのが、PSGI/Plackという訳です。これによって、既存のWAF側の対応が簡単になります。事実、CatalystのPSGI対応というものも既に出来ていますし、後述しますがその他のWAFも極めて簡単に対応出来るようになりました。
3.3. パフォーマンス
PlackのパフォーマンスはHTTP::Engineより同じか、むしろ速い程度とのことでした。上記のようなリクエストおよびレスポンスのオブジェクトを作らないだとか、HTTP::Engineにあった色々な補助処理(HTTPレスポンスヘッダーの補完など)がないことなどが主な理由です。
Plackでも、或る程度の段階でベンチマークを取るとのことでしたので、じきに数字で明らかになる方向であるようです。
ただ、それが速かろうが遅かろうが、PSGIやそれに対応したWAFという大船にさえ乗っていれば、パフォーマンスをカリカリにチューニングしたPSGI仕様の別実装を使えば良いのです。例えば後述のmod_perlite/mod_psgiなどの実装です。繰り返しですが、PSGIは仕様・Plackは実装、ですね。
3.4. 非同期やその他
現状のWAFでは難しい、ストリーミングのようなサーバープッシュ型のサービスでも、PSGI/Plackの非同期(async)関連対応により簡単に実現出来ます。Any::Eventをバックエンドするもので、実際にデモでも動かしていただけました。
Plackで面白い他の点としては、plackupという便利なユーティリティーコマンドも付いていることなどが挙げられます。
このように、HTTP::EngineからPSGI/Plackへの転進は、地滑り的な方向転換ではなく、むしろ定常進化と言えるような物だと強く感じました。
4. HTTP::Engineは停止、ただし後方互換性は維持
HTTP::Engineについては、致命的バグの修正やセキュリティーfix以外での保守開発は行われないだろう、ということです。
といっても後方互換性は維持するということなので、今使っている人も一安心といったところではないでしょうか。トークでも語られたように「仕事で使っている人もいる」ことにも配慮いただけています。他の一連のコーポレートトラック(企業でのPerl活用事例トーク)でも、結構な範囲でHTTP::Engineが使われていることに驚きましたが、そういう場合でも安心ですね。
PSGIの仕様は上記のように特別複雑なことを求めている訳ではありません。といってもシンプルが一番難しいということを、最近とみに思い知らされています。閑話休題、複雑でないということは既存のWAFをPSGIに対応することについての障壁が比較的低い(CGI用の実装とほぼ同様)ということを意味しています。
5. PSGI/Plackの今後
5.1. 世を席巻するPSGI/Plack
感想を記した前の記事では記していませんでしたが、村瀬さん(typesterさん)のArkに関するトークで言及された通り、出来合いのWAFを使うのではなく、(HTTP::Enginの登場によって)目的に特化したWAF(オレオレWAF)を自作することが容易になりつつあります。
PSGI仕様は、そうした昨今の流れをさらに加速する牽引車となるのではないでしょうか。
既存のHTTP::Engine利用WAFはそのままでも使えますし、Plack対応したりPSGI準拠にすることも出来ます。一方、これからWAFを作る人は、Plackとそのアダプターを用意すればさらに楽になります。
私が熱く注目しているArkでも、既にPlackブランチが切られていたりします。HTTP::EngineのPSGIアダプターも既にありますし、Catalystについても同様です。CGI.pmのメンテナーの方からも好感触を得ているとのことで、このPSGIの素晴らしさはあっという間に世を席捲しつつあります(CGI::ApplicationやJiftyといったWAFはCGI.pmを使っています)。つまり、仲立ちとなる仕様や実装の本命と目されていて、Perlでの本流となることが強く期待出来ます。
5.2. さらなる展開へ
PSGIやPlackはCPANに上げる予定だとのことです。また、これらが色々なところで標準となれば、(DateTimeのように)perl.orgのサブドメインを貰いたいという話もありました。つまり、準公的な立場を目指したいということですね。
また、Perl6のコアモジュールにしてもらいたいというお話もありました。上記のCGIモジュール(CGI.pm)がPSGIに対応すれば、(CGIはcorelist CGIで分かるようにPerl 5.004からコアモジュールなので)自然体でPSGIが(Perl5の)コアモジュールに含まれるという話もあります。Perl5でもPlackがコアに入ればいいな、と思いました。
Perl6では、Perl5の言語仕様的な妥協のない、また違ったPSGI/Plackの姿を見られるかも知れません。
トークの中では、(昔ちょっとニュースに出て、最近ちょっと進んでいなさそうな)Google App Engine for Perl (GAE/Perl)へPSGIの採用を働きかけているというお話も聞けました。これが実現すれば、PSGI対応WAFに載ったWebアプリケーションをGAEで運用出来るという、薔薇色の未来が待っています。
Rubyでは"Heroku"というPaaS(Platform as a Service, ハードウェアに基盤的ソフトウェアをセットにしたホスティング環境)があり、Rackに対応したSinatraなどのWAFを動かせます。一方PerlにはRackやWSGIのようなものがなかったので、それがISPなどに受け容れられない理由ではないか、というのは宮川さんの見解でした。
さらに、宮川さんの元同僚の方によるmod_perlite(モッド・パールライト)というApacheモジュールに入れてもらう(mod_psgiという名前になるかも)働きかけをしているという話も飛び出て期待が高まります。mod_perliteは恥ずかしながら始めて知ったのですが、これはいいApacheモジュールですね。この動きによってもたらされる恩恵ついては後述します。
このように、お二人の熱いトークを通して、PSGI/Plackをメジャーな存在とするのだ、という強い志向を感じました。
6. エンドユーザーへの恩恵
WAFユーザーにとっては、PSGIという共通基盤に準拠したWAFをよりどりみどりで選べるようになったり、現在お世話になっているWAFの開発がさらに促進されるという意味で恩恵があります。しかしそれでけではなくて、レンタルサーバー屋やISPに間借りして何かWebアプリを作る私のようなエンドユーザーにも、大きな恩恵がもたらされる可能性があります。仕事でWebアプリを作ることがほぼ見込めない私にとっても、です。
6.1. レスポンス時間の問題
PerlはLLの中では比較的高速な言語ですが、それでもMouseでなくMooseを使ったり、色々なモジュールを使ったりする場合には、その立ち上がりの時間(ロードおよびコンパイル時間)の塵が積もって山になってしまいます。
通信時間や画面描画時間を含めたレスポンス時間についての現実的な線は、
- 照会系の処理であれば1~3秒
- 検索系であれば(クエリにもよりますが、簡単な物であれば)照会系と同様
- 更新系の処理であれば(これもクエリにもよりますが、大抵は)3~5秒
程度が許容されうるところではないでしょうか。7秒でユーザーが逃げてしまうだとか、色々な実証研究結果があるように、レスポンスは必須ではないですが、それでも限度という物がありますよね。上記は勤め先の性能テストでの目標値とは異なりますが(首が飛ぶので、流石に値は書けません)、例えば私が日曜プログラミングで書くようなシステムは、業務システムのような「閉じた系」ではありませんし。
6.2. CGIでは辛いがVPSは高い
大抵の日曜プログラマーは、高価なレンタルサーバーやVPS(Virtual Private Server; 仮想専用サーバー)のサービスを契約しているのではなくて、さくらインターネットやXREA/Coreserverといったレンタルサーバーであるとか、或いは自分のISPのスペースを間借りしてサービスを提供していることと思います。
そうした場合の最大の悩みは、永続化環境の欠乏です。つまりCGIでしか動かせなくて、FCGI(Fast CGI)やmod_perlの提供がほぼ望めないという問題です。
CGIでも現実的なレスポンス時間を叩き出せる脅威のWAFであるArkを使わせていただいている私でも、将来的な不安はやはりあるもので、海外の格安VPSを使うかも知れないと考えています。格安といってもそれなりの値段はするので、貧乏サラリーマンの趣味として気軽に契約するのには二の足を踏んでしまいます。
6.3. PSGI/Plack経由でFCGIやmod_perl的な永続化環境が使えるようになるかも?
ところがPSGI/Plackがさらにメジャーな存在になって、サーバー管理者側がPSGI仕様に準拠したmod_perlite(mod_psgi)やPlackなどのモジュールを用意してくれれば、もしかしたらFCGIやmod_perlと同様の永続化環境を使える余地が出るかも知れないのです。
もうちょっと噛み砕くと、そのままFCGIやmod_perlを使うと、何でも出来てしまうので、例えば共用サーバーの場合には(同居人などへの)セキュリティー面での懸念が出ます。ところが、Apacheが(mod_perliteモジュールで)PSGIを喋るようになれば、そうした懸念が払拭出来るのではないでしょうか。
別に既存のISPやレンタルサーバー屋が首を縦に振ってくれなくても、Perl版HerokuのようなPaaSが、GAE/Perlや他の新興サービスとして出てくれれば良いわけです。
永続化環境のもう一つの問題であるリソース面では、特に(常時メモリに載ると言うことで)RAMの心配もあるでしょうが、それは他の方のトークでもあったような「RAMを買ってくれ」ということですね。
この指摘は問題のサーバーが自社(や自分)のものであるという想定ですが、レンタルサーバー屋のユーザーでもこれは期待出来ます。なぜなら、サーバー機であれば64bit対応のOSを入れてしまってもそろそろ問題なくなって来たからです。64bitの広大な世界にあかせて、RAMを潤沢に積んだとしても、べらぼうな値段の構築費が掛かるわけではありません。
一昔前のハイエンドサーバーが、今ではその辺のレンタルサーバー屋さんの最下等プランの容れ物として提供されているくらいですので、RAMの心配は早晩払拭されるのではないかと、私は予想しています。富豪的プログラミングというのはコンピューター科学の定常進化の方向性だと私は思っていますので、レンタルサーバー屋さんにはこうした面での差異化を期待したいところですね。また、Herokuのような新たなビジネスのチャンスかも知れないので、機に聡い起業家の登場も期待したいです。
7. 全体を通して
何しろYAPC::Asia 2009の数日前に始めてブログで知ったPSGI計画ですので、概要を予習して(今年の会場である)大岡山に出掛けていった私は、「HTTP::Engineが再整理されるが、まああまり自分に大きな影響はないだろう」と考えてしまっていたのですが、それは大間違いでした。
多くのWAFとWebサーバー側のインターフェースを仲立ちするということを、彼らは本気になって推し進めようとしています。繰り返しますが彼らは本気です。その熱気に打たれました。そしてそれが成った未来を想像すると、PerlのWebアプリケーション界隈がさらに活気づくのではないかと、身震いがしてきました。その身震いは、部屋の冷房が私に直撃していただけが理由ではなかったと感じます。
これからも大いに注目したいですし、私のようなエンドユーザーが出来ることを探していきたいです。
PSGI/Plackの仕様や実装に提案や意見などを上げることが出来なくても、PSGI/Plackが落ち着いて、mod_psgi構想が実を結んだら、これらの導入をサーバー管理者へ要望するなどといったことが挙げられます。例えばXREA/Coreserverでは、CPANモジュールなどのインストール要望を掲示板で出せるようになっているので、そうしたチャネルを活用したいところですね。
コメントする