2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
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などが構成されていると言えます。
(次回につづく)
関連タグ:
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
2024.12.12
今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦
2024.12.11
大企業への転職前に感じた、「なんか違うかも」の違和感の正体 「親が喜ぶ」「モテそう」ではない、自分の判断基準を持つカギ