
2025.03.07
クレームを入れた人の3割は、「1時間以内」が我慢の限界 メールの初動対応で失敗しないための具体策
リンクをコピー
記事をブックマーク
macopy氏:というわけで、mod_perlの話をします。mod_perlは「Apacheの中にPerlのインタプリタを組み込んでしまいましょう」という発想(のこと)ですね。
Apacheの中にもMPMという、どういうふうにプロセスを立ち上げておくか、リクエスト・レスポンスを処理するかを決めるモジュールがあります。それによってプロセスやマルチスレッドを処理したりするんですが、そのワーカーの中にmod_perlがロードされて、その中にPerlインタプリタが組み込まれています。
Perlプログラムを読んで、CGIを模したリクエスト・レスポンスをプログラムに与えてあげて、レスポンスを返す。これはもちろんCGI以外でも使えます。
Apache2とかにも関連しますが、1996年にmod_perl、2002年にmod_perl2(が出ました)。本来はApacheの機能拡張をPerlで行えるようにするモジュールですが、多くの場合はCGIプログラムをそのまま効率よく動かすために使われます。ModPerl::Registryとか、そういうHandlerを設定しておけば、CGIとの互換性を保ったまま高速化できるという売り込みだったんですね。
ただその反面、CGIの場合はプロセスがリクエストごとに終わっていたのが、もっと長くなってしまった。なので、昔のCGIプログラムはグローバル変数をかなり多用しているんですが、アプリケーションの状態をグローバル変数に保持してプログラムが書かれている場合に、CGIでは暗黙的に起動時に必ずグローバル変数が初期化されていたのが、mod_perlでは初期化がされないために動かなくなってしまうことがありました。
というわけで、PerlのCGIプログラムをmod_perlで動かします。hello.cgiをアップロードしましたが、先ほど言ったようにperlディレクトリの中でもmod_perlが動くようになっています。jcode.plですね(笑)。jcode.plも使っているから……。(画面を示して)こんな感じで、先ほどと同じものを映しました。同じようにパーミッションを変更します。
会場:なぜパーミッションを600ではなく644に変更する必要があるのか?
macopy:Apacheと上げているFTPのユーザーが違うからなんですよね……。
会場:了解。
macopy:補足ありがとうございます。.plでmod_perlのHandlerが動くようになっています。一応これも755でやっておきます。
その後にhello.plもちゃんと動くようになります。
ただ先ほど言ったように、普通のCGIと違ってmod_perlはプロセスが永続化されているので、リロードしても変わらないということがよくわかります。
じゃあスライドに戻ります。いろいろな視点があると思いますが、類似品としてはmod_mrubyだったりmod_luaだったりがあります。ほかに言語ごとに(も)あります。裏を返せばmod_perlはPerl専門家です。
同じようなものがApache以外にない(の)かというとあって、ngx_http_perl_moduleがあります。これはnginxでも同じようなことをするためのモジュールです。CGIとかはあまり関係がありません。
次にFastCGIです。FastCGIが何かというと、これは先ほどのmod_perlと違って言語非依存です。ただFastCGIはmod_perlと同じで、プロセスが永続化されています。
じゃあ、その永続化されたプロセスとApacheのワーカー間での通信はどうなっているか。これは普通に標準入力と標準出力だったらいいけれど、立ち上げた時じゃないと環境変数はそのまま渡すことができないじゃないですか。
だからどうしているかというと、UNIXドメインソケットを使って、その中でバイナリプロトコルで通信されているHTTPのリクエスト・レスポンスがバイナリプロトコルに変換されて、FastCGIプロセスとApacheのワーカーが協調して動くかたちになっています。
これによってCGIのデメリットであった、プロセスが起動したり終了したりというコストが減って効率化できるし、FastCGIプロトコル自体がリクエストの多重化に対応しているので、スレッドを使ったり(できる)。例えばイベントドリブンという感じで、1つのプロセスが複数のHTTPリクエスト・レスポンスを扱える状況になっても対応できるのがメリットだったということですね。
というわけで1996年、奇しくもmod_perlとだいたい同じ(時期)。CGIプログラムの高速化は、けっこう明確に打ち出していました。一方で、先ほど言ったように(FastCGIは)言語非依存なんですが、弱点としては、完全なdrop-in replacement(になっています)。mod_perlみたいにCGIプログラムをmod_perlのほうにそのまま動かすのはできるんだけれど、FastCGIではそれはできなかったということですね。
ただ、セマンティクス。例えばさっき言ったクエリストリングだったりだけは引き継いでいる感じです。あと、先ほど言ったように多重化もできています。
というわけで、FastCGI向けのプログラムを動かしていきます。fcgi/hello.fcgi、(FastCGIと)同じようなやつです。
ただこれはCGI.pmと互換のモジュール(である)、CGI::Fastを使っています。なので、生でsayとかをやっていたのよりはけっこう効率化されています。とりあえず1行空を出力することもないです。(画面を示して)こんな感じですね。
途中からEncode.pmを使っています。jcode.plだとちょっと面倒くさかったので(笑)。最後にpid=$$もやっています。こいつをそのままデプロイします。
デプロイはまたFileZillaでやります。fcgi-binにデプロイします。パーミッションの変更。
先ほどのjcode.plはもう使わなくなったのでアップロードしません。で、こんな感じです。
(会場拍手)
ありがとうございます(笑)。先ほどEncode.pmとか(が)使えるようになったので、こんな感じで……。どっかでミスったかな、文字化けしますね。mod_perlと同じで、これをリロードしてもpidは変わりません。こんな感じです。じゃあ戻ります。
実はSpeedyCGIというFastCGIの類似品もありました。(それは)PersistentPerlとも呼ばれます。これはCGIプログラムのshebangをPerlからSpeedyに変えるだけで、FastCGIみたいにプロセスの永続化をある程度してくれるやつです。
ただプロセスは永続化してPerlからはCGIと同じような感じで起動しますが、そこで小さいプログラムが起動して、もともと起動しておいたプロセスと入れ替えて実行することをやってくれます。でも、最近はあまり見ないですね。
というわけでPSGIの話をしていきます。ちょっと毛色が変わりますね。2009年にspecがCPANにshipitされたんですが、ただこの頃はWebフレームワーク群雄割拠時代で、CatalystとかCGIとかFastCGIとかmod_perlとか、それぞれで再実装をしていた時代になっていた。
そこで「フレームワークに依存せず、言語のシンプルなインターフェイスでそれぞれのHandlerを扱えるようにしましょう」という(ことで登場した)のがPSGIだったということです。なので、Plack::HandlerでCGIとかmod_perlの実装もあります。
ただ、この頃になってくると、Perlとかはランタイム自体がHTTPサーバー、HTTPをしゃべるようになってきたんですね。それまではあんまりしゃべるということはなかった。TomcatとかJavaとかはあったかもしれないけれど。そういうわけで、リバースプロキシという概念が一般になり始めたり、Apache以外の選択肢が出てきた。
じゃあPerlはどうしていたかというと、Plack::HandlerとしてStarmanとかStarletといったPrefork型のHTTPサーバーが実装されて、今となってはこれも現役で使われるようになりました。
じゃあPlack/PSGIは……。というより、HTTPサーバーをランタイムで立てる手法についての説明です。
Apacheはただただ、HTTPのプロトコルを後ろに受け流すリバースプロキシをするだけで、PerlではPrefork workerが動いていて、こいつらがマルチプロセスをうまく使って、HTTPリクエストを受けてレスポンスを返すというかたちになっていた。
というわけで、これはデプロイしませんが、生PSGI、つまり「Plackとかに頼らない生のPSGIはどんなものかを書いてみた」というものをサクッと説明しようかなと思っています。(画面を示して)こんな感じですね。
セマンティクスは、QUERY_STRINGみたいなのがCGIからもけっこう引き継がれているんですね。$envという引数を受け取る無名関数subがあって、この$envの中には、CGIの時代のものから引き継がれているPATH_INFOだったり、QUERY_STRINGといった環境変数がハッシュのキーとなって入っているということですね。
こんな感じでパースして$nameを取ってあげる。この$bodyというのは、PSGIの場合、最後に配列リファレンス3つで返すというルールがあるんですが、配列リファレンスの最後の要素に、配列リファレンスで囲って$bodyを入れてあげるということですね。あとヘッダーをcharset=utf-8で入れる。で、200という(結果が出るという)ような感じですね。じゃあ戻ります。
あとPSGIの類似品というかほかの言語ではどうしているかというと、一番古いのは、調べたところJava Servelet APIなのかなという感じです。その後にPython。これは発音があれなんですがWSGIとか、RubyだとRackとかがあって。
ちなみにおもしろいことに、例えばRackのspecの中にはWSGIに関する言及があったり、WSGIのspecの中であるPEP 333にもJava Servelet APIの言及があります。
PSGIとは何か。これはあまり調べていないんですが、JavaScriptのケースの場合はWSGIとRackとJSGIの言及があります。けっこうほかの言語から取り入れる時代になったのがこのあたりということですね。
あとPlackの類似品をインターフェイス視点で言うと、先祖としてはCGI.pmが最初にあり、CGI::ApplicationとかApach::Request。あと、直接的な先祖としてはHTTP:Engineだったり、それの参考になったCatalyst::Engineだったり。このあたりのモジュールの要素が組み合わさって、PSGIやPlackなどが構成されていると言えます。
(次回につづく)
関連タグ:
2025.02.27
「頭のいい人」がやらない行動7選 職場でできる人に見られる、「心の知能指数」を高めるポイント
2025.03.03
大企業で成功したマネージャーが中小企業で苦戦する理由 “指示待ち”部下を主体的に動かす方法
2025.03.04
チームが協力しないのはマネジメントの問題 “協働意識”を高めるマネージャーの特徴とは?
2025.03.03
2064年もエンジニアで稼ぎ続けるには Python歴20年のベテランが語る、生成AI時代のキャリア戦略
2025.01.28
適応障害→ニート→起業して1年で年収1,000万円を達成できたわけ “統計のお姉さん”サトマイ氏が語る、予想外の成功をつかめたポイント
2025.02.28
40歳以降の人間関係は「年下」との交流が肝 『移動する人はうまくいく』著者が語る、職場で評価される秘訣
2025.02.27
成功する・しないの差は「時間」と「場所」の違いだけ 『移動する人はうまくいく』著者が語る、仕事も住む場所もどんどん変えるメリット
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.02.26
フリーターから年収1億近く…『移動する人はうまくいく』著者の人生遍歴 そこそこ良い会社に就職するより経済的に成功する考え方
2025.03.05
「はい、わかりました」と返事をした部下が“かたちだけ動く”理由 主体性を引き出すマネジメントの鍵
2025.02.27
「頭のいい人」がやらない行動7選 職場でできる人に見られる、「心の知能指数」を高めるポイント
2025.03.03
大企業で成功したマネージャーが中小企業で苦戦する理由 “指示待ち”部下を主体的に動かす方法
2025.03.04
チームが協力しないのはマネジメントの問題 “協働意識”を高めるマネージャーの特徴とは?
2025.03.03
2064年もエンジニアで稼ぎ続けるには Python歴20年のベテランが語る、生成AI時代のキャリア戦略
2025.01.28
適応障害→ニート→起業して1年で年収1,000万円を達成できたわけ “統計のお姉さん”サトマイ氏が語る、予想外の成功をつかめたポイント
2025.02.28
40歳以降の人間関係は「年下」との交流が肝 『移動する人はうまくいく』著者が語る、職場で評価される秘訣
2025.02.27
成功する・しないの差は「時間」と「場所」の違いだけ 『移動する人はうまくいく』著者が語る、仕事も住む場所もどんどん変えるメリット
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.02.26
フリーターから年収1億近く…『移動する人はうまくいく』著者の人生遍歴 そこそこ良い会社に就職するより経済的に成功する考え方
2025.03.05
「はい、わかりました」と返事をした部下が“かたちだけ動く”理由 主体性を引き出すマネジメントの鍵