xtetsuji) です。
おがた (@2015年4月3日(金曜日)、1社目で最後まで一緒に働いていた後輩と二人で久々に飲み会をしました。そこで考えて語ったレガシー開発論など、公開しても良さそうなところを書いてみます。私は2014年1月に退職していますが、後輩は今も在職しています。
飲み会 (@ 居酒屋 だいぶつ in Shibuya, 東京都) https://t.co/Xl4yJEqZRK pic.twitter.com/yA7ekhowXX
— OGATA Tetsuji (@xtetsuji) April 3, 2015
書きたいことはざっと書いたのですが、推敲がうまくできなくて長文になってしまいました。暇な時に流し読みしていただくのがちょうどよいかもしれません。長いブログ記事、Kindleで電子出版したほうがいいかもしれませんね…。
執筆依頼やモジュール類のドキュメント化依頼は随時受け付けていますので、この勢いで文章を書いて欲しいという方がいらっしゃいましたら、ぜひご依頼ください。
Contents
そこはmod_perlの世界
1社目で使われている開発言語は主にPerlです。ただ、ウェブプログラミングの実行環境はモダンなPlackなどではなく、2003年に採用されたmod_perlが連綿と使われ続けています。ちなみに当時はmod_perl1でしたが、2010年過ぎにmod_perl2に移行されました(作業担当は全部私で、ブランチを切ってコードを書き換えてほぼ一発で移行させました)。
2009年に登場してPerl業界の事実上の標準となったPlack採用の機運を盛り上げようとしたこともありましたが、ミドルウェア採用に関する圧倒的な発言力を有していた「インフラ部署」が「極度の保守」の姿勢を取っていたこともあり、開発部署にはmod_perl以外の選択肢は無かったのでした。
今日の大多数のPerlプログラマーにとってこれは不幸なストーリーに聞こえますが、今までの社内の流れを踏まえた上で改めて考えると、そこまで悪いことではなさそうだと思ったのが今回の話です。
以下の記事も参考になるかもしれません。
- YAPC::Asia Tokyo 2012 に参加して、mod_perlネタで発表もしてきました #yapcasia
- 「モダンmod_perl入門」のこれまでとこれから #yapcasia
- YAPC::Asia Tokyo 2013 で「Apacheの展望とmod_perlの超絶技巧」というトークをしてきた話など #yapcasia
- 最近の私とmod_perlとの関わり
どこまで行っても隣の芝は青いだけ
後輩は私のブログを読んでいて、私が行き当たりばったりで京都や福岡に行って色々な人と会って交流したことをうらやましがっていました。ただコチラからすると、無職独身でブラブラするほかないより、仕事があって家族がいて自分が若いうちに子供が成人するほうがうらやましいです。
そんなことを飲み始めに後輩と話をしていましたが、独身か既婚かっていうのは典型的な隣の芝は青い論争になるんだなと思います。
配偶者子供持ちは自由な時間がある独身をうらやましがり、独身は家庭がある配偶者子持ちをうらやましがる。この分野ではとことん隣の芝は青いよなぁ。
— OGATA Tetsuji (@xtetsuji) April 25, 2015
後輩も私もこのオープン系ウェブ業界でプログラマーをしているわけで、新しいものに興味はあります。プライベートで取り組むことができるかは別として、仕事でそういう新しいものを導入できないことは、ある種の進化を断念させられたような悔しい思いをすることだってあります。
とはいえ新しいものを導入できたとして幸せかというと、必ずしもそうではないのかなと今は思います。楽しくはあるけれど、結局は新しいもの特有の技術的負債が生まれたり、枯れていないものを採用すること自体が事業のリスクになったり、それなりに負の側面をもあるのかなと。酸っぱいブドウのように受け取られるかもしれませんが、別の場所の開発体制を見聞きすればするほど、そういう考えも浮かんできます。
昔の私も今回一緒に飲んだ後輩もそうですが、会社の方針でレガシー開発をしている多くの人は有名企業の人達が最新技術で開発している話を聞いてうらやましがるわけです。ただ結局は隣の芝は青いだけで、実は隣はいいことばかりではないのかもしれません。
特殊な「インフラ部署」と、アンチクラウドのビジネスモデル
プログラミングなど開発にはそれなりの時間がかかりますが、サービス自体が終了するまでのライフサイクルを考えると、開発よりも保守運用の時間のほうが圧倒的に長いことがほとんどです。ゼロからの開発手法は注目されますが、保守運用の手法こそもっと注目されるべきなのです。人によって想像する内容が違う流行語「DevOps」は、まさにその辺を注目したいという人々の意思の表れなのでしょう。
1社目でも、開発と運用保守が未分化だった時代(だいたい2005年頃か)に、何でもできるスキルがある特定の人に仕事が集中してしまうという問題点を解消するために開発と運用保守が分業体制になりました。具体的にはプログラミングを行う開発部署と、100台弱のオンプレのサーバ群の面倒を見る「インフラ部署」です。
わざとカギ括弧付きで「インフラ部署」と書いたのは、世間のオープン系ウェブ業界が言うインフラ部署との違いの強調です。これはクラウドとは一切関わらず、各種設定ファイルと多少のシェルスクリプトは書くものの、プログラミングというものを行わないと宣言している部署です。以下、カギ括弧が無く当該部署をインフラ部署と書くこともありますが、それを指すものと思ってください。程度の差はあれ、オンプレを有している企業にはこのような部署があるのではないでしょうか。それの良し悪しについて、今は判断を保留します。
アンチクラウドを標榜するのは世相に逆行していると思うのが普通でしょうが、これはビジネス上の戦略の一つでもあります。そう、同じようにアンチクラウドを標榜する日本の古式ゆかしい大企業を顧客に持つためです。このような企業は、自社データをアメリカのどこにあるのか分からないサーバに置くことなんてとんでもないばかりか、自社のデータは自社の閉域ネットワーク上にあるサーバ以外には保存すらさせたくないと思う会社があるのです。
とはいえ、日本企業のクラウドに対する抵抗感は年々無くなっていることは事実であって、このようなビジネスモデルは先細りであることは言うまでもありません。言ってしまえば新たなビジネスを開拓するまでのつなぎでしかないのですが、当事者全員がそういう危機感を持っているかと言われるとそうではなかったような気がします。
世間のオンプレを有しているオープン系ウェブ業界は、大概はインフラ部署というものがあって、何かの導入の際には開発部署が折衝することになります。往々にして安定稼働という旗印の前に、開発部署はインフラ部署に比べて弱い存在になりがちです。私のいた1社目の最後のほうはそれが顕著でした。おおよそ業界では当たり前のミドルウェアも、安定稼働以外の納得できる理由が提示されることなく、導入を否決されることが当たり前となっていました。
元々は、インフラから開発まで何でも出来る達人の負荷を減らすために生まれた分業が、今では開発ができない(開発側の事情を理解しようとしない)「インフラ部署」が開発部署を抑えこむことになってしまったのです。ミドルウェアなどの導入をほぼ禁止された開発部署は、パラダイムシフトを起こすどころか、開発意欲の減退すら危ぶまれます。
程度の差はあれど、これは開発とインフラの分業を発生させたオンプレの比重が高い企業が陥りがちな問題でしょう。インフラ部署に求められる安定稼働が当然のものと受け取られ、何か問題を起こせば減点査定というインフラ部署に対する評価自体も問題ではあります。ただ、インフラ部署の地位を上げて開発部署を縛るようになると、新しい製品の萌芽を摘み取ることにもなりかねません。企業が成熟して新サービスのリリースが滞る要因の一つなのかもしれません。
この部分を的確に捉えて問題解決が出来る上層部や経営層は多くないように思えます。この問題に直面している現場の人達は「DevOps」という言葉にすがるようにしているわけですが、結局はまっさらな状態から全部クラウド上にサービスを展開させて、全てのインフラ関連業務がプログラミングによって掌握できるプログラマー天国な世界にした上で、開発とインフラの分業を無くしてしまうという方法くらいしか解決策が無い気がします。既存のプログラミングができないインフラ部署の高齢エンジニアに今さらプログラミングを新たにやってもらうという流れにもなりづらいですし、かといってオンプレに求められる力仕事というものが、このホワイトカラーが全面に押し出されたIT業界でいつまでも受容されつづけるとも思えません。
結局はクラウド移行で「プログラマー天国」にするという流れは、既存のオンプレに支えられているコードを書けないインフラ部署の方々の職を奪いかねないものです。そんなことは発言力を持ったインフラ部署自体が許すはずもなく、その発言力をもってしてクラウド移行を阻止するというジレンマは考えすぎでも何でもなく、実は少なくないオンプレ企業が抱えている問題ではないでしょうか。
memcachedの採用は拒否されるものの、tcp/80 に “GET /” のHTTPリクエストを投げれば監視ができるmod_perlで書いた自作KVSは採用されるのです。無能な私が書いた何ら信頼出来ないKVSであることを説明しても、インフラ部署には関係ありません(アプリでバグが出ることは彼らには関係無いのです)。
そんな状況が生んだのが、mod_perlで「超絶技巧」を行う私と、mod_perlに支えられる企業とウェブサービスでした。
mod_perlに依存していく経緯
1社目でもともと2003年にmod_perlが導入されたときは、mod_perlはPerl CGIの高速化という意味合いでしかありませんでした。つまりApache::Registryを使うという世界観。
Apacheのpreforkプロセスの肥大化問題の対処のために、当初からApache::SizeLimitなどのmod_perlモジュールが使われましたが、社内でmod_perlモジュール(ハンドラ)を書き始めるのには時間が必要でした。
2004年頃には、一回り年上の先輩方が「mod_perlが…」と口々に言うようになっていました。Perl CGIとmod_perlの違いが分からなかった私は、数少ないmod_perlの和書を読み尽くして、当時出版されていた2冊の洋書を読み始めます。ろくに英語が分からなかったのですが。
mod_perlの真の意義はPerlでApacheを拡張することだと理解した時点で、先輩方の理解は失礼ながらそこまでは至れていないことに気づきます。
2005年頃から自分が開発を牽引する形で小さなウェブサービスを量産していくことになります。この中で、少しずつmod_perlで作ったApache拡張機能を試していくことになります。
当時、私主導で小さなウェブサービスを大量に載せていたウェブサーバ群は、大量のバーチャルホストを抱えることになり、私が関わっていないサービスで導入を余儀なくされたクローズドソースのApacheモジュールによってApacheの安定性が損なわれ、私が面倒を見ていた他のサービスへの悪影響も出てきました。そういう経験から、私の権限ではクローズドソースなApacheモジュールの導入は一切許可しない方針を取っていました。
当時の会社は、今で言うガラケー向けのウェブ開発を行っていました。標準化が行き届きつつある今日から見たらガラケー向けウェブ開発なんて完全にバッドノウハウで食う世界です。バッドノウハウをみんなで吸収しようという試みは当時から細々とあって、たとえばゆめみがガラケー開発用のApacheモジュールを公開したりしていましたが、結局はクローズドソースだったこともあり、導入には踏みきれませんでした。
結局はmod_perlの威力を知った自分自身が、ガラケー開発の諸問題を解決するようなmod_perlハンドラを書いて対処するようになりました。この方法論であれば、他所で開発されたPHPプログラムにmod_perlハンドラを適用させてPerlで機能拡張をすることもできます(出力フィルタはmod_perl2を待つ必要がありましたが)。
この頃には当時インフラを一手に引き受けていた先輩の尽力もあり、インフラ部署との分業体制になっていました。しかし、その先輩はインフラ部署との分業を最後の仕事にして退職してしまいます。この時点ではインフラ部署のトップになった方の豊富な経験やプログラミングへの理解もあり、開発部署との連携はうまくいったものでした。
2009年ごろには不採算事業が軒並み整理されて、私が開発に携わった小さなサービスは例外なくサービス終了か他社へ移管されることになりました。私は職を失うことなく、主力事業であるウェブメール部門へ移ることになりました。
創業当時からの開発者の先輩によって、ウェブメールの内側は相当作りこまれたシステムとなっており、その先輩が1社目最後の上司となりました。ミドルウェアの導入に関しては主力事業のこちらでも慎重な姿勢が取られていましたが、上司の奇想天外な手法の数々でApache+mod_perlとOracleのみであらゆることが行われていました。
メールというシステムは受信も送信も即時性を保証しないプロトコルです。リクエスト受理からレスポンス送信まで1秒が長時間とされるウェブの世界では、メールの送受信によってHTTP通信の総時間が長引くことはユーザ体験を損なう以前に、ウェブサーバの同時接続数を増やしたりといったシステム上の諸問題も生まれます。当然ながらジョブキューなどは無い(導入が許されない)世界です。上司のプログラムでは、例えばALRMシグナルを巧みに使った上で、長時間が想定された時はApacheのpreforkプロセスをexecで切り離したりするコードがところどころにありました。これは良い解決策にも思えますが、Apacheのpreforkプロセスをレスポンス処理フェーズでexecで切り離すことは、Apacheのプロセスライフサイクルを理解したうえで考えると禁忌です。なぜならログが書けないから。Apacheの親プロセスは、execでいなくなったApacheの子プロセスを充足するので、その点は問題ありませんが。
この時点でインフラ部署は、当初のトップの方が退職され、 残った方々による「極度の保守」体制になっていました。諸問題を解決するためにジョブキューを導入するという話にも今さらなるはずはありません。開発物全体の見通しの良さや拡張性という話は彼らには関係ない話です。
cronとRDBMSを組み合わせた自社開発ジョブキューという線もありましたが、もっとも手軽だったのが、時間がかかる処理をレスポンス処理フェーズからログ処理フェーズよりも後にあるクリーンナップフェーズに追い出すことでした。mod_perlのRegistryスクリプトでCGI.pmまたはその継承モジュール(CGI.pmを継承することの是非は置いといて)を使っている場合、CGI#r メソッドにてmod_perlリクエストオブジェクトを取り出して、APR::Pool#cleanup_register メソッドでクリーンナップフェーズに処理を差し込むことができます(mod_perl2の場合)。上司にヒアリングしつつ、このような修正を行ったりしていきました(サーバ実装によりますが Plack でも$env->{‘psgix.cleanup.handelrs’} で同様のハックができます)。ただ、あまりにも長時間かかる処理をクリーンナップフェーズに回すと、全てのpreforkプロセスがそれにかかりっきりになり、ウェブサーバ全体が無応答になる可能性もあるので注意が必要ですが、クリーンナップフェーズでexecして親のApacheから切り離すことは問題ありません。
当時の経営陣の愚策にかまけて数年間放置されつづけたウェブメール部署も、数年ぶりに新機能の開発が叫ばれました。新たなミドルウェアの導入が難しいことは開発側の暗黙の理解となっており、この時点でmod_perl2を最大限に活用した機能がいくつも生まれます。代表的なものはSMTPサーバでした。
このような経緯で、1社目がmod_perl色に染まっていき、自分もmod_perlのスキルを半ば求められるかのように伸ばしていくことになるのでした。
mod_perlで行き詰まる場合、そうでない場合
2009年にPlackが生まれるまでは、FastCGIと二分したPerlのウェブアプリケーション実行環境がmod_perlでした。2008年頃までは、ウェブ開発言語としてPerlを採用していた企業の大半は、FastCGIかmod_perlを使用としていたと言っても過言ではないでしょう。
2009年以降Plackが席巻したとはいえ、2014年頃までmod_perlで構築されたシステムは各社に色濃く残っているものでした。例えば、YAPC::Asia Tokyo 2013 で @lestrrat さんがトークした「本当にあったレガシーな話」は有名です。
レガシーmod_perlシステムを抱える各社の方々と話をしていて、mod_perlで構築されたシステムが負債を抱える一つの分岐点は「Apache::Requestモジュールを使う」ことかなと現時点では考えています(ここではmod_perl1での話)。
一般的なシステムは疎結合的設計で組まれていたほうが拡張性(スケーラビリティ)の面では有利であることは良く知られた事実です。私が考える理想的なmod_perl開発でも機能を細分化し、機能毎にmod_perlハンドラを作り分けて適切なApacheの各種フェーズに設定します。機能の大半が集中するだろうレスポンス処理フェーズには、直接mod_perl依存のコードを書かず、何らかの別レイヤーを作ることでしょう。この別レイヤーは、しばしば「ウェブアプリケーションフレームワーク」と呼ばれるものです。
「Apache::Requestモジュールを使う」ことがなぜシステムが負債を抱える分岐点なのでしょうか。1つ目はレスポンス処理フェーズをmod_perlと密に作ることの現れであること。2つ目はApache::RequestモジュールがPerlのウェブプログラマーが思うようなHTTPリクエスト抽象化モジュールではないことです。
mod_perlと心中するつもりがあるにせよないにせよ、Perlプログラムレベルで速度を極限追求するのでなければ、あるまとまった規模以上のウェブアプリケーション(レスポンス生成プログラム)はmod_perlとは別のレイヤーで書いたほうが拡張性も高いと考えます。mod_perlが提供するオブジェクト指向ハンドラがレスポンス処理フェーズでは特段のメリットをもたらさない(ように思える)ことも一因です。これに関しては私の経験からそうだとしか言えないので、もっと違った見方もあるとは思います。
HTTPリクエストを抽象化するモジュールとして、古くはHTTP::RequestやCGI.pmといったモジュールがありました。その後、CGI.pm互換モジュールや、各種ウェブアプリケーションフレームワーク付属の抽象化モジュールにて洗練されていき、Catalystが持つCatalyst::Requestにて大体のデザインが確定したように思えます。その後、Plack前夜のHTTP::Engineが持つHTTP::Engine::Requestが登場したあと、今ではPlack::Requestモジュールが多くのリクエスト抽象化モジュールの下地となっています。Mojoliciousが持つMojoツールキットのMojo::Message::Requestなど、今でもPlack::Requestに依存しないものはあります。
では、Apache::Request モジュールは上記のような思想のリクエスト抽象化モジュールかというと、厳密にはそうではないと私は考えます。では何なんだと言われたら、それは「libapreqへのPerlインターフェース」であると答えますし、libapreqは何なんだと言われたら「C言語で書くのはしんどいリクエスト解析処理を肩代わりしてくれるApacheモジュール開発支援ツール」であると答えるでしょう。
Apache::Requestモジュールは、受け取ったリクエストに対してウェブプログラマーが求める大部分のリクエスト抽象化は提供してくれるものの、例えば提供されたそれの内容を一部改変したりといった部分が弱点だったりします(特にmod_perl2のApache2::Requestが顕著)。これはApache::Requestをベースに自分独自のリクエスト抽象化モジュールを書く場合の障壁となります。Apache::RequestモジュールのPODには、自身を継承するサブクラスの作り方について言及されていますが、ここで安易に継承を使うとmod_perlとの密な関係がさらに強固になってしまうというジレンマが。そもそも、往々にして継承を使った設計は好ましくない密結合を生みがちで、委譲のほうが好まれます。大部分のアプリケーションロジックが集積するレスポンス処理フェーズでこのような方針が取られると、mod_perlアプリケーションとしての拡張性も、Plackなどの他のインターフェースへの載せ替えも、困難さを伴うものになるのではないかと考えます。むしろレスポンス処理フェーズでは原始的なCGI.pmやその互換モジュールを使ったほうがマシなのではないかとすら思えます(レスポンス処理フェーズよりも前段のフェーズで CGI->new することは、POSTやPUTのメソッド時にボディを消費してしまって、肝心のレスポンス処理フェーズでボディが無いという事が起こるかもしれません)。
ありがたいことに、mod_perl開発に関して色々な方から相談を受けたり語り合うことがありますが、実際の私はmod_perlハンドラ上に直接巨大なコードを書いたこともなく、Apache::Requestモジュールを使ったコードを商用環境に投入したこともありません。レスポンス処理フェーズでも直接書くのはせいぜい数百行ですし、それなりの規模の機能を入れるならワンクッション入れて独立した機能のモジュールを書きます。そのほうがテストもし易いですし、将来的にmod_perlだけで行くつもりであっても良いことが多いのです。
Plackでは、小さな Plack::Middleware::* を組み合わせて自分が欲しい機能を実現することが普通のこととなりました。それとだいたい同じことができるはずの mod_perl なのですから、一枚岩のロジックに苦しむ必要など本来は無いはずなのです。ただそのコードが前任者による仕業であるなら、同情するほかないのですが。
mod_perlを勉強し始めた比較的早い段階からそれに近い考えには至っていたので、1社目に残したコードでmod_perlゆえのジレンマというコードはそれほど無いはずです。手前味噌ではありますが、むしろ読んでいて楽しいコードにしたと言ってもよいくらい。それに文章を書くのが嫌いではないので(そうでなければこのブログが長文になるはずはない)、相当手厚いPODを残していることも自信材料ですね。
mod_perlシステムが負債を抱える分岐点については、それぞれの人がそれぞれの感想を抱くかなと思います。私も確定的に上述の通りだとは言えないものの、感覚的に分かりやすいのはApache::Requestかなと思っているところです。
やる気があればプログラマーを始めるのが遅くてもなんら関係ない
今回一緒に飲んだ1社目最後の後輩は、20代の終わりにこの会社に転職する以前は飲食業に従事していて、プログラマー経験もIT業界勤務経験もありませんでした。
そんな後輩は、趣味でPerl CGIを勉強してDBを使ったウェブアプリケーションを書いたりしていたらしいのですが、IT業界に転身したいと相談したどの転職エージェントにも「30代手前でIT業界への転身は厳しい」と言われたそうです。本当に転職エージェントはゴミ以外の何者でもないですね!(転職エージェント大嫌い)
後輩も30歳になるまでのわずかな期間でIT業界に行けなかったら諦めようとしていたそうですが、結果的に上司と私の面接でIT業界に来てもらうことができました。本当に良かった。
手前味噌ではありますが、教育好きの私によって、今ではLinuxの基本的な仕組みからウェブアプリケーションのなりたちなどを一緒に語ることが出来るくらいにまでなりました。でも多くのエンジニアにありがちな謙遜癖が彼にもあるので、すごいねといっても謙遜するばかりなのですが。彼が平均的なプログラマー以上に勤勉であることは事実なので、当然ながら誰でもなりたいと思ってプログラマーになれるとは限りません。でもそれは若くても一緒。
今回も飲み屋でmod_perlの話を振ったりしても普通に会話出来ていたので、30代で3年目くらいの職業プログラマーだけれども、今や会社にとって重要な戦力だと言えるでしょう。
「教育をしないオープン系ウェブ業界」という問題は様々な活動で解決していきたいと考えています。そもそもプログラマーは需要過多が急激に進む業種であることは明白なので。まずは身近な人達を育てることから。そしてPerl入学式のような多くの初心者を対象にした活動から、さらに構想中のこれから…。ご期待ください。
Mojolicousとmod_perl、そしてModPerl::PSGI
私が1社目を去る直前は、社内や社外の規模の大きくないアプリケーションをMojoliciousで開発してリリースするまでの一連の流れを作ったりしていました。
「ただやるだけじゃないの?」と言う方はうらやましい方。そう、我々はCPANモジュール一つ商用環境に追加するだけでインフラ部署と交渉しなければならないのです。これが依存関係で大量のCPANモジュールを引っ張ってくる場合、その交渉は絶望の域。でも幸いなことに、Mojoliciousは明示的な依存関係を一切持っていません(Mojo::IOLoop::ClientでSSL通信をする場合にIO::Socket::SSLをオプショナルでrequireしたりはしますが)。我々のような「環境」ではMojolicousが最適解でした。
問題はそれだけではありません。新しいデーモンプロセスを立てたい場合、インフラ部署から、どう起動すべきか、サーバの再起動時どうすべきか、どう監視すべきか、などといった種々雑多な質問群を受けることがあります。実際、memcachedも導入してもらえなかったので、現状の道具でなんとかなるのであれば最後の方はもう面倒になって交渉にすら行かなくなりました(無駄に嫌な気分になりたくないので)。Mojliciousの場合、morboやhypnotoadを使わないとなるとどうするとよいでしょうか。CGIは避けたいですよね。
みなさんのご想像の通り、我々mod_perl集団はmod_perlで動かそうとするわけです。ただ、mod_perlで動作させるとなるとMojoliciousをPlackで動かさないといけない。Plackは依存関係が…という不安もよぎります(何の不安もない環境がうらやましいわけですが)。
私が在職していた時に作ったのは社内ツールだけだったのでPlackを黙って入れてしまいましたが、私の退職後にMojoliciousで作った商用サービスを投入したという後輩はどうしたか聞いたところ、私が作っていたModPerl::PSGIというモジュールを使ってくれたという話でした。
そもそも私がModPerl::PSGIを作った経緯は、Plackにある Plack::Handler::Apache2 が Apache2 が持つ prefork 以外の MPM 環境への対応が甘いことから、これのソースコードを手元で抜き出して種々のMPM対応などを入れた上で、Plack本体への依存を一切なくしてPerlコアとmod_perl2にのみ依存関係を絞ったものです。その他、依存解消ついでにURL解析などをPlackのPure Perlコード(Plack::Util など)から高速な APR(Apache Portable Runtime:Cで書かれたApacheの共通ライブラリ) へ差し替えたりしました。このただひとつのモジュールファイルを Apache2 の設定ファイルに指定することで、mod_perl2 による PSGI 実行環境ができます。worker MPM などにも適切に対応しています。詳細なベンチマークは取っていませんが、Plack::Handler::Apache2 よりはパフォーマンスが良いと思います。
後輩によると、Plackの導入はできそうだったものの、テスト環境で Plack::Handler::Apache2 + Mojolicious を試したところ、どうもMojoliciousの挙動がおかしい場合があり、それもあってModPerl::PSGIにしたら微調整でうまくいったこともあり、私(おがた)にPull Requestを送った上で商用環境に投入したとのこと。
後輩の調査によると、どうもMojolicousがPlackに渡すPSGIアプリケーションが、良く知られた3要素を持つ配列リファレンスではなく、サブルーチンリファレンスだったときに問題がありそうだったという話。ただ、そのあたりはPlack::Handler::Apache2 から ModPerl::PSGI への移植時には特に考慮しなかったよなぁ、とか思いつつ色々と話をしていました。
知っている方にはおなじみだと思いますが、PSGIアプリケーションがサブルーチンリファレンスを返す場合は、遅延レスポンスやコンテントストリーミングを実現する場合などです。
Plack::Handler::* の方針
後輩が Plack::Handoer::Apache2 ではなく ModPerl::PSGI に Pull Requets を送ったのは、Plack のコア開発者よりも私のほうが身近だったからというのもあります。私が Plack::Handler::Apache2 に直接さまざまなMPMへの対応を入れなかったのも、Plack のコア開発者が雲の上の存在だったからというのと似たような理由ですね。まずは ModPerl::PSGI で実績を出して、それを Plack::Handler::Apache2 に成果を取り込んでもらう流れのほうが話が通りやすいかなとも考えていました。
そう、YAPC::Asia Tokyo 2013 の懇親会で、あの @miyagawa さんとお話する機会があり、Plackの方針について聞く機会がありました。
そもそも Plack のコア開発者の中には mod_perl を使っている人はもういないらしく、そもそも Plack に同梱されている Plack::Handler::* にある様々なウェブサーバの対応自体をコア開発者だけで行うのはいささか大変とのこと。今後は Plack から Plack::Handler::* が分離されるかも、というお話を聞きました。
現状では(といっても2013年のことですが)、海外の一部の企業が mod_perl2 対応のためにパッチを送ってきているだけとのことで、Plack のコア開発者もそれを比較的そのまま取り込んでいるだけのようです。
Plack::Handler::Apache2 が切り離されたら、自分もメンテナに名乗りでたいものですが、自分もそれほど現役で mod_perl2 を使いこなしていると行ったらそれほどでもないので悩ましいところ。とりあえず、event や worker などの各種MPMへの対応は入れたいですね。
特に日本のPerlの動向を左右するほどの雲の上の存在な方々による議論のことを、界隈では尊敬の念を込めて「円卓会議」と呼んだりするのですが、その円卓会議のリアルバージョンを撮影した方がいらっしゃるようです。
#yapcasia A round table meeting pic.twitter.com/FINVwmKJ6N
— Kang-min Liu (@gugod) August 29, 2014
こういうところに加われるようになりたいものですね。
事業においてPlackが直接金を生むのではない
新しいものを取り入れていきたいし、余暇で新しいものを勉強していくべき我々オープン系ウェブプログラマーではありますが、自分が古いものを使っている立場として痛感したのは、古いものを使っている人に対して上から目線になってはいけないということ。
よく私がネタを交えて言うのは「キモーイガールズになってはいけない」というやつです。
これがキモーイガールズです(はてなセリフより)。
新しいものを取り入れる人は、ついつい自分が古いものを使っている人より優位に立っていると錯覚しがちです。ただ、よく考えてみてください。往々にして新しいものが直接金を生むわけではないんです。
「世の中カネか?」と言いたい人もいるかもしれませんが、会社員として働いている限りは当然収益のことを意識しなくてはならないでしょう。
確かに、絶望的にこんがらがったmod_perlアプリケーションのコードを目の前にして、今後の拡張性のためにPlackに移植したいという気持ちはわかります。ただ、そのアプリケーションは本当に今後の拡張が期待されるものでしょうか。そこそこ以上の規模であれば決して楽ではないだろうPlackへの移植作業に見合った拡張を施す前にそのサービスは終了してしまうかもしれない。新しいものが次々と出てくる界隈ですが、それだけ既存のサービスも短命なわけです。今はグッとこらえて要求された小改良を続けていたら、いつのまにかサービス終了が決まっていたなんてこともよくあることです。
livedoor Blog のように、今後10年戦えるようにしなければならない重要な製品もありますが、残酷かなたいていのサービスは10年生き延びることはありません。こんなことをいうと会社員プログラマーとして会社のことを考えているのかと言われてしまいますが、冷静に製品を観察して、見込みが無ければさっさと新しい製品を新しい技術で開発したほうがいいのではないでしょうか。
世の中のオープン系ウェブ企業の企画職という人達の多くがイノベーターやアーリーアダプターと呼ばれる人ではなく、既に流行しきったものから二番煎じを作るくらいのスキルが普通だということも理解しておいたほうがいいと思います。もちろん、この職種の優秀な人は何人も知っていますが、IT開発者以外のIT業界の職種の人達は往々にしてITのことを知らないということは、悲しい事実として受け止めておくべきです。この話は長くなりそうなので、別記事で書くことにしましょう。
そういえば私は2010年に一度就職活動をしていました。その活動の中でも、誰もが知っている大手IT企業の孫会社の面接が印象的でした。エンジニア数人が面接官だったのですが、彼らからPlackを使っているかという質問をされました。当時は特にPlackに興味のなかったので(Plackが登場してまだ半年くらい)、「話は聞いたことあるけれど、触ったことはないです」と正直に言ったところ、PerlのウェブプログラマーなのにPlackを知らないとはどうかしているとか、本当にやる気あるのかといった罵詈雑言を言われた経験があります。ただ、その会社は数年後に無くなってしまいました。
mod_perl企業が細々と生き続け、真っ先にPlackに飛びつきPlackを知らない人に心ない言葉を浴びせかける企業が無くなってしまう。新しいものが直接金を生むわけじゃないんです。小規模であればCGIだって立派な方法論です(むしろモーニングバグなど小規模特有のバグを避けるためにプロセスの永続環境を避けるべき場面もある)。
正直言えば、私はプログラマーとしてはレイトマジョリティ寄りなんだと思います。流行るか流行らないか分からないものに学習コストを割けないという人種。その代わり、既に人口に膾炙したものの定式化や文書化は徹底的にやるというタイプ。あとは仕様から論じることが好きなので、ちゃんとした仕様があるものに対して実装を議論することも好んでやります。人はみんな得意不得意・向き不向きがある。
その後2013年に就職活動をしていて面白かったのは、社内にmod_perlアプリケーションを抱えている企業からは不採用で、mod_perlと無縁な企業から採用を頂けたということ。mod_perlアプリケーションを抱えている企業は、既にmod_perlで散々嫌な思いをしていることは想像に難くなく、そんなものを推進される恐れのある人間なんて入れたくないということでしょう(Plackへの移行も適切にやりますよ、とは言ったのですが…)。逆にmod_perlとは無縁な企業は、私がmod_perlでのプレゼンスを持っていることを「一つのことを極められる人は、他のことも極められる」と買ってくれたようです。興味深いですね。
後輩と飲み交わしながら、PSGIアプリケーションがサブルーチンリファレンスを返す時のmod_perl上での実装について語ったりしていましたが、Plackであることを威張って人を見下す人達のどれくらいがPSGIの仕様で語られている遅延レスポンスやコンテントストリーミングのことを理解しているのか、興味深いところです。
前述の「キモーイガールズ」の原作では、キモーイガールズは最後にひどい目に会って物語が完結するらしいのですが、原作を手に入れて読んだことがありません。とはいえ原作は成人指定なので、手に入れても多くの人に見せられないでしょうし、教訓入りの寓話のように気軽に参照はできないわけですが…。
mod_perlの今後もしばらく安泰だろう
Nginxに押されて一時期ほどの存在感は無くなったApacheですが、今後も開発は継続されていくことでしょう。
Nginxを前衛に立たせて静的コンテンツを配信し、動的コンテンツへの要求は後衛に配置されたPlackなどのアプリケーションサーバにリバースプロキシするというお馴染みのやり方も、今後は変わってくるかもしれません。多くの場面で使われているAWSですが、ELBがもっと賢く運用が楽になれば、静的コンテンツはCloudFrontに入れて、ELBが静的コンテンツと動的コンテンツへのアクセスを直接振り分けるという方法も現実味を帯びてきます。
開発バージョン mod_perl2.0.9 として、mod_perl2 の Apache2.4 対応も遅まきながら進められています(遅れている理由の一つはWindows上のApache2.4の存在らしいですが、最近ウォッチしていません)。event MPM がもっと枯れてくれば Nginx と有意な差が無いサーバとして新たに台頭してくるかもしれませんし、Apache の良さを活かしたイベント駆動ウェブサーバが欲しい場面もあると思います。
Nginx と Apache を比較しつつ、ウェブプログラマーとして多くのウェブサーバをウォッチしていきたいですね。
制限された環境は面白くもある
2012年頃から、1社目では新しいものを取り入れることを半ば諦めつつありました。私には否決される交渉に割く時間など無いのです。その代わり、mod_perlだけで何でもやってやろうという一種の野望めいたものが生まれました。制限された環境を味わい尽くす方がネタになるという気持ちもあったわけです。
ただ、今が伸び盛りの後輩にとっては、ちょっと可哀想かなという気もします。彼なりにインフラ部署と無関係なところで新しいものを取り入れようとAngular.jsに取り組んだり等しているようですが、もっとサーバサイドで新しいことに挑戦させてあげたいなとも。
結果的に、制限された環境というものができて、そこで私は一種のプレゼンスを獲得したわけで、結果的にインフラ部署に与えられたものがあると言ってもいいのかもしれません。Plackを極めても注目されるような面白ネタにはならなかったと思います。手前味噌ながら、私が在職中に整備したmod_perlワールドは解説も多く整然としていると自負しており、世間でmod_perlに苦しんでいる企業とは違って後輩を苦しめたりはしていないと信じています。それは今回後輩と飲み交わして、より確固たる考えに変わりました。
ニコニコ動画には「制限プレイ動画」というジャンルのゲームプレイ動画があります。例えばスーパーマリオブラザーズで、ずっとマリオが後ろ向きの状態でクリアしたり、可能な限り点数を取らなかったりなど。
制限プレイが面白いのは既にそのゲームをやり尽くしたからであって、最初から制限プレイをして面白いゲームはほとんど無いんじゃないかと思います。mod_perlという「ゲーム」も、それをやり尽くした私だから面白いだけで、後輩には「クソゲー」として映っていないかは心配です。
とはいえ、今回は色々と楽しく議論もしたし、また出来る限りの「攻略本」も在職時に書いたつもりなので、後輩の頑張りを期待しつつ、たまに飲み会を開いて相談に乗ってあげようと思います。