モダンmod_perl入門     (Modern mod_perl Guide)     尾形 鉄次 (OGATA Tetsuji)         Twitter: @xtetsuji  2012/09/29 YAPC::Asia Toky...
Attention for audience• This slide is mainly written by Japanese, and  few English. In the future, I will write and  share...
Self-introduction
自己紹介• 尾形 鉄次 (OGATA Tetsuji)• Twitter: @xtetsuji• Blog: http://post.tetsuji.jp/• SlideShare: http://www.slideshare.net/xtet...
所属紹介• 株式会社fonfun(フォンファン) http://www.fonfun.co.jp/ • 主力製品:リモートメール   http://rmail.jp/
Agenda
Agenda• About mod_perl basics• mod_perl handler basics• Refactoring mod_rewrite• mod_perl meets PHP• Apache worker MPM and...
If time is left• Compare with others• Connection cycle:  Let’s make SMTP Server by mod_perl• Other topics
In the first
Respect for ...               モダンPerl入門(翔泳社 2009; http://books.shoeisha.co.jp/book/b73388.html )
参考文献• 洋書になりますが、mod_perlを勉強する 上で役立つ3冊 • Practical mod_perl   (Orelly 2003; http://modperlbook.org/) • The mod_perl Develope...
About mod_perl basics
History of mod_perl• mod_perl1 first public release: 1996/3/25  (see: http://perl.apache.org/dist/mod_perl-1.0-current/Chan...
Perl CGI の高速化• mod_perl1                                           # ↓Apache Configurations              AddHandler perl-sc...
Perl CGIの高速化• CGI.pm、CGI::Simple 等は内部で mod_perl高速化環境をサポート済み• とはいえ永続環境なので、グローバル 変数の扱い等注意が必要 →モダンPerlなコードを書こう
mod_perlって何?• Perl CGIの高速化?→副次的な効果• 本当は「Apacheがモジュールで提供す る機能をC言語を使わずPerlで書ける ようにしたもの」がmod_perl• C言語が読み書きできない俺歓喜
About mod_perl basics• Perl CGIの高速化についてはだいぶ割愛 させていたきますが、世間に出回って いる間違った知識の是正だけはどこか でしたい• 後はApacheのmod_perl拡張ハンドラを 読み書きして楽しみ...
mod_perl handler    basics
mod_perl essence is extension of Apache• mod_perl の Perl CGI高速化環境では、 HTTPリクエストを受けてレスポンスを 返すことが出来るのは周知の通り• mod_perlはHTTPレスポ...
Apache internal• MPMは多く使われているpreforkを想定• 親プロセスを起動すると、設定に従って 子プロセスを設定の数だけ起動(prefork)• 各子プロセスはHTTPリクエストを待つ• では子プロセスごとのHTTP処理...
Apache internal•   リクエストを受ける•   ヘッダを解析する•   必要に応じてURLを変換したり、DocumentRootを手がかりに実パスを    割り出す•   アクセス制御、認証、承認(BASIC認証など)•   M...
Apache internal• 各処理を行っている部分にはフックが あって、ここに各種処理を挟むことが 可能 → Apache Module(mod_xxxxxx)• Apache Module でできることを Perl でできるようにしたも...
Apache/mod_perl   process phase• 各フックがある部分: 「(処理)フェーズ」• リクエスト待ち状態から各フェーズを 一巡するので、全体を 「リクエストサイクル」と呼びます
Phase of mod_perl1           PerlChildInitHandler       PerlPostReadRequestHandler               PerlInitHandler          ...
Phase of mod_perl1            ※「Practical mod_perl」より抜粋
Phase of mod_perl2         PerlChildInitHandler     PerlPostReadRequestHandler             PerlInitHandler            Perl...
Phase of mod_perl2            ※「Practical mod_perl」より抜粋
first mod_perl1 handler   package MyApache::Hello;   use strict;   use warnings;   use Apache::Constants qw(OK);   sub hand...
first mod_perl2 handlerpackage MyApache2::Hello;use strict;use warnings;use Apache2::RequestRec (); # for $r->content_type(...
Apache{1,2} configs   # Apache1   <Location />      SetHandler perl-script      PerlHandler MyApache1::Hello   </Location> ...
first mod_perl handler• 全ては sub handler と $r の受け取りから • これはどの処理フェーズでも同様• mod_perl2 では $r のメソッド群が各種 別パッケージで管理されているため、 メソッドによっ...
first mod_perl handler• PerlHandler / PerlResponseHandler にハン  ドラをセットしておけば、全てのファ  イルの処理をフックできるので、*.html  ファイル等をあたかも透過的に処理す ...
Refactoringmod_rewrite
About mod_rewrite• URLを書き換えるApacheモジュール• 「Apacheのスイス製アーミーナイフ」• 簡単なコードでURL書き換えが可能だ けれど、数十行も書けば魔窟の完成• 黒魔術と呼ばれる理由
Refactoring       mod_rewrite• mod_perl では PerlTransHandler という  URL を書き換えるフェーズを用意して  いる• ここに URL 変換処理を挟める
Apache1 URI Transpackage MyApache1::Trans;use strict;use warnings;use Apache::Constants qw(DECLINED);sub handler {    my $...
Apache2 URI Transpackage MyApache2::Trans;use strict;use warnings;use Apache2::RequestRec (); # for $r->uri()use Apache2::...
Apache{1,2} configs   # Apache1   # e.g. In <VirtualHost> Directive   PerlTransHandler MyApache1::Trans   # Apache2   # e.g...
mod_perl URI Transpros than mod_rewrite• mod_rewriteに比べて可読性が高くなる• DBを引いたりmemcachedにアクセスし たりPerlで出来ることは何でもできる
mod_perl URI Transcons than mod_rewrite• 複数のファイル管理が必要となる(*.pm)• Perl/mod_perlが分からない担当者への  引き継ぎが難しくなる• Directory Context(<L...
mod_perl meets PHP
PHP pathetic story of   Perl Monger• 誰かが発注したアプリがPHP製で、既に 勝手に納品しちゃっている• 蓋を開けると実装とかがテキトウ過ぎ• 契約や諸々の理由で手を入れられない• 運用担当でPerlしか知ら...
mod_perl meets PHP• PHPが実行される前後にmod_perlで何か フックを差し込めないか • PHP処理前に認証・許可処理 • PHP処理後に出力をフィルタ…等々
Review request phase
Access/Authen/Authz      and PHP• session_*()の使い方等がダメなケースで  は、PHP中のそれらのコードを除去して  mod_perlのAccess/Authen/Authzフェーズ  で対処するケー...
package MyApache2::Auth;use strict;use warnings;# $r->headers_in() and $r->headers_out() returns APR::Tableuse APR::Table ...
Request output filter     and PHP• PHPの出力をフィルタする• Apache2のネイティブフィルタなので、 PHPの ob_*() (output buffering) 等の設定 に一切影響されない• 応用例:...
Requets output filter      practice• Filter の場合 sub handler { ... } は  $r (Request Object)ではなく、  $f (Filter Object) を第一引数に受...
package MyApache2::FilterObfuscate;use   APR::Table          ();use   Apache2::Filter     ();use   Apache2::RequestRec ();...
PHP and Perl are friend• Apacheの上でPHPとPerlは友達!• 他にも各種フックを使ってmod_perlは PHPを助けることができる• 可能性は無限大
Apache worker MPM and Perl ithreads
Apache worker MPM and Perl ithreads• Apache worker MPM: スレッド(pthread)  とプロセスのハイブリット動作• Perl ithreds: 嫌われ者 • 同時並行処理するならPara...
スレッドのメリット• 各リクエストフェーズ間で変数共有が 可能 (poor man’s memcached?)• 何か人とは違う事をしてるワクワク感
スレッドのデメリット• Perl ithreadsが安定していない• 各スレッド毎にインタープリタプール を作成する設計上、preforkとコストは それほど変わらない• スレッドセーフを意識する必要がある
Instruction worker   MPM & mod_perl• worker MPM上でのmod_perlのノウハウ は特に少ないのでハマると危険• Perlのスレッドは不安定である事を心得 た上で、複雑な事はさせてはいけない
Queue server by   mod_perl2 thread• 今回はスレッドの変数共有を利用した  mod_perl2の文字列Queueサーバを実演• “POST /” でRequest BodyをQueueing、• “GET /”...
Queue server by mod_perl2 thread (1)package My::Queue;use strict;use warnings;use threads;use threads::shared;my @queue :s...
Queue server by mod_perl2 thread (2)package MyApache2::ThreadQueue;use strict;use warnings;use threads;use Apache2::Reques...
Queue server by mod_perl2 thread (3)### continuedsub handler {    my $r = shift;    if ( $r->method eq POST ) {        my ...
worker MPM andperl ithreads practice• 複雑な事はさせてはいけない• 複雑な事をさせる場合には十分試験を• 大事なことなので(ry• 前出のQueue serverは100KB程度の文字 列の入出力を10K/...
compare mod_{lang}     families
mod_{lang} (1)• mod_perl: 最も歴史が古いものの一つ• mod_ruby: 開発停滞状態→mod_mruby• mod_python: 開発停滞状態• mod_lua: Apache2.4からコアモジュール• mod_m...
mod_{lang} (2)• mod_wsgi: Python WSGI 実装• mod_php: いわゆるPHP • こちらは今までの意味でApacheを  「拡張」するものではない• 他にもたくさんmod_{lang}はあるらしい
Benchmark     http://blog.matsumoto-r.jp/?p=2669 より
Benchmark     http://blog.matsumoto-r.jp/?p=2669 より
Benchmark• Perl CGI高速化環境(PerlRun, Registry)の  場合はmtime(ファイルの最終更新日時)  を都度見るので、statシステムコールの  コストが無視できない• mod_perlネイティブハンドラで勝負!
Benchmark• 実際、mod_perlネイティブハンドラで  同等のベンチマークを行うと  About 7000 Response/secとのこと  (Thanks @matsumotory)• Yet another perl5 imp...
In future my activities
In future my activities• mod_perlの役立つ情報やコードを公開 していきたい• mod_perlで困っている人を助けたい
In future my activities• 今後もmod_perl界隈を盛り上げたい• Twitterアカウント作った @mod_perl_info• ウェブサイトも作成中(未完成) http://modperl.info/• 詳細、割愛...
Timeup?
Questions?
☆Service Slides☆
Compare with others
Compare with others• Pure CGI• FastCGI• PSGI/Plack, WAF
mod_perl and     pure CGI• パフォーマンスを要求しなければ良い• Apache以外のウェブサーバでも使える• レンタルサーバ等、mod_perlすら使え ない環境は未だに多い
mod_perl and FastCGI• どちらも同じ永続環境、適材適所• Apache拡張ならmod_perl、CGIの高速化 のみならFastCGI• mod_perlの場合Apacheプロセス自身が 肥大化していくことを嫌う向きもある
mod_perl and  PSGI/Plack, WAF• モダンなウェブアプリを今から書くの であればPlackベースのWAFを選ぼう• Apacheを拡張して他の言語との連携や Apache自体の動作を拡張できるのは mod_perlの面...
Should you choice     mod_perl?• Apacheという枠の中ではあるものの、 mod_perlの可能性はとても広い• パフォーマンス、移植性、様々な要素 を検討して、mod_perlを使うか考える• 既にあるApa...
Connection cycle: Let’s make SMTPServer by mod_perl
Connection cycle• HTTP以外のサーバを書きたい• Apacheと同様の安定性が欲しい• Apache2/mod_perl2では、Connectionを HTTP以外の自前のものに書き換える事 ができる (e.g. mod_s...
AboutConnection Cycle   PerlPreConnectionHandler PerlProcessConnectionHandler                        ※「Practical mod_perl」...
Why I want to write SMTP server by perl• DB引きたい• 絵文字処理したい• 通常のMTA(Sendmail/qmail/Postfix等)の pipeではスケールできない
Qpsmtpd• http://smtpd.develooper.com/• 実際に私(会社)もmod_perl2 Connection cycleでSMTPサーバを実装してみたもの の、既にPerl界隈にはQpsmtpdという MTAがある
Qpsmtpd has some  Engine=Transport• pipe (CGI like)• fork-server• prefork-server• Apache (Apache::Qpsmtpd)• async (Danga::...
Qpsmtpd’s   Apache::Qpsmtpd• Apache2 / mod_perl2 の Connection cycle  の良い応用例• これを見るとApache2をEngineとして  MTAを作る方法が良く分かる
Other topics
Test of mod_perl        handler• 「モダンPerl入門」に詳しく書いてある• Apache2::FakeRequestを使って偽物の$r を作ってハンドラをテストできる• 処理単位のテストはTest::More等...
nginx:  HttpPerlModulehttp://wiki.nginx.org/HttpPerlModule
nginx:   HttpPerlModule• 構文や考え方がmod_perl1と酷似 →mod_perlの知識を流用可能• ただしイベント駆動サーバならではの 各種制限もあるので注意• 世間での応用例も少し出てきている• 以前はEmbedd...
nginx:HttpPerlModulepackage hello;use nginx;sub handler {  my $r = shift;  $r->send_http_header("text/html");  return OK i...
nginx:    HttpPerlModule• mod_perl2ではなくmod_perl1の構文の 影響を強く受けている ($r->send_http_headers()等に見られる)• nginx設定ファイルの書き方については 割愛→前...
割愛したこと• Perl CGIの高速化環境の詳細• Apache2.4環境でのmod_perl→現時点 (2012/09)で正式にサポートしていない• Apache2.4 event MPM環境での mod_perl→上記同様
これからのApache• Apache2.4でmod_perlがサポートされた ら、event MPM上でmod_perl動かしたい• Apacheはこれからも進化していきます• mod_lua, mod_sedがApache2.4でコアモ ジ...
Questions?
ご清聴ありがとうございました
モダンmod_perl入門 #yapcasia
Upcoming SlideShare
Loading in...5
×

モダンmod_perl入門 #yapcasia

7,763

Published on

YAPC::Asia Tokyo 2012 の 2日目9月29日の夕方のトーク「モダンmod_perl入門」のスライドです。

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,763
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
20
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • &amp;#x5F53;&amp;#x7136;Apache1&amp;#x3068;Apache2&amp;#x306E;&amp;#x6B74;&amp;#x53F2;&amp;#x306F;&amp;#x305D;&amp;#x308C;&amp;#x3088;&amp;#x308A;&amp;#x524D;\n2003&amp;#x5E74;&amp;#x306B;&amp;#x306F;Apache2/mod_perl2&amp;#x304C;&amp;#x51FA;&amp;#x3066;&amp;#x3044;&amp;#x305F;&amp;#x3051;&amp;#x3069;&amp;#x3001;&amp;#x5F53;&amp;#x6642;&amp;#x306F;&amp;#x307E;&amp;#x3060;&amp;#x3053;&amp;#x306A;&amp;#x308C;&amp;#x3066;&amp;#x3044;&amp;#x306A;&amp;#x304B;&amp;#x3063;&amp;#x305F;&amp;#x306E;&amp;#x3067;&amp;#x3001;2003&amp;#x5E74;&amp;#x306E;&amp;#x30EA;&amp;#x30E2;&amp;#x30FC;&amp;#x30C8;&amp;#x30E1;&amp;#x30FC;&amp;#x30EB;&amp;#x7B2C;4&amp;#x4E16;&amp;#x4EE3;&amp;#x306F;Apache1.3/mod_perl1&amp;#x3067;&amp;#x4F5C;&amp;#x6210;&amp;#x3057;&amp;#x307E;&amp;#x3057;&amp;#x305F;\n
  • &amp;#x66F8;&amp;#x3044;&amp;#x305F;&amp;#x3053;&amp;#x3068;&amp;#x304C;&amp;#x3042;&amp;#x308B;&amp;#x65B9;&amp;#x3082;&amp;#x591A;&amp;#x3044;&amp;#x3001;&amp;#x57FA;&amp;#x672C;&amp;#x3067;&amp;#x3059;&amp;#x306D;\n&amp;#x30B9;&amp;#x30DA;&amp;#x30FC;&amp;#x30B9;&amp;#x306E;&amp;#x90FD;&amp;#x5408;&amp;#x3067;&amp;#x6539;&amp;#x884C;&amp;#x3092; \\ &amp;#x3067;&amp;#x30A8;&amp;#x30B9;&amp;#x30B1;&amp;#x30FC;&amp;#x30D7;&amp;#x3057;&amp;#x3066;&amp;#x3044;&amp;#x307E;&amp;#x3059;&amp;#x3002;&amp;#x5B9F;&amp;#x969B;&amp;#x306B;&amp;#x3053;&amp;#x3046;&amp;#x3044;&amp;#x3046;&amp;#x66F8;&amp;#x304D;&amp;#x65B9;&amp;#x3082;&amp;#x3067;&amp;#x304D;&amp;#x307E;&amp;#x3059;\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • &amp;#x30FB;worker&amp;#x3059;&amp;#x306A;&amp;#x308F;&amp;#x3061;&amp;#x30B9;&amp;#x30EC;&amp;#x30C3;&amp;#x30C9;&amp;#x3068;&amp;#x3044;&amp;#x3046;&amp;#x3082;&amp;#x306E;&amp;#x3082;&amp;#x3042;&amp;#x308A;&amp;#x307E;&amp;#x3059;&amp;#x304C;&amp;#x3001;&amp;#x30B9;&amp;#x30EC;&amp;#x30C3;&amp;#x30C9;&amp;#x30BB;&amp;#x30FC;&amp;#x30D5;&amp;#x306A;Perl&amp;#x30D7;&amp;#x30ED;&amp;#x30B0;&amp;#x30E9;&amp;#x30E0;(&amp;#x3044;&amp;#x3084;&amp;#x3001;Perl&amp;#x306B;&amp;#x9650;&amp;#x3089;&amp;#x305A;)&amp;#x306F;&amp;#x96E3;&amp;#x3057;&amp;#x3044;&amp;#x306E;&amp;#x3067;&amp;#x907F;&amp;#x3051;&amp;#x307E;&amp;#x3059;\n
  • \n
  • \n
  • &amp;#x30FB;&amp;#x5358;&amp;#x306B;&amp;#x300C;&amp;#x30D5;&amp;#x30A7;&amp;#x30FC;&amp;#x30BA;&amp;#x300D;&amp;#x3068;&amp;#x3082;&amp;#x8A00;&amp;#x3044;&amp;#x307E;&amp;#x3059;\n
  • &amp;#x30FB;&amp;#x7686;&amp;#x3055;&amp;#x3093;&amp;#x306E;&amp;#x8208;&amp;#x5473;&amp;#x306E;&amp;#x3042;&amp;#x308B;&amp;#x30EC;&amp;#x30B9;&amp;#x30DD;&amp;#x30F3;&amp;#x30B9;&amp;#x51E6;&amp;#x7406;&amp;#x3092;&amp;#x30AA;&amp;#x30EC;&amp;#x30F3;&amp;#x30B8;&amp;#x3067;&amp;#x5857;&amp;#x3063;&amp;#x3066;&amp;#x3044;&amp;#x307E;&amp;#x3059;\n&amp;#x30FB;PerlHandler Apache::Registry &amp;#x3068;&amp;#x306F;&amp;#x30B3;&amp;#x30EC;\n
  • &amp;#x30FB;&amp;#x51E6;&amp;#x7406;&amp;#x30D5;&amp;#x30A7;&amp;#x30FC;&amp;#x30BA;&amp;#x3092;&amp;#x4E00;&amp;#x5DE1;&amp;#x3057;&amp;#x305F;&amp;#x30EA;&amp;#x30AF;&amp;#x30A8;&amp;#x30B9;&amp;#x30C8;&amp;#x30B5;&amp;#x30A4;&amp;#x30AF;&amp;#x30EB;&amp;#x306E;&amp;#x56F3;&amp;#x3067;&amp;#x3059;\n&amp;#x30FB;&amp;#x3053;&amp;#x308C;&amp;#x306F;Apache1&amp;#x306E;&amp;#x56F3;&amp;#x306A;&amp;#x306E;&amp;#x3067;&amp;#x3001;Perl*Handler&amp;#x3067;&amp;#x306F;&amp;#x306A;&amp;#x304F;&amp;#x5F79;&amp;#x5272;&amp;#x540D;&amp;#x306E;&amp;#x82F1;&amp;#x5358;&amp;#x8A9E;&amp;#x306B;&amp;#x306A;&amp;#x3063;&amp;#x3066;&amp;#x3044;&amp;#x307E;&amp;#x3059;\n&amp;#x30FB;&amp;#x7C21;&amp;#x5358;&amp;#x306B;&amp;#x8AAD;&amp;#x307F;&amp;#x66FF;&amp;#x3048;&amp;#x3067;&amp;#x304D;&amp;#x307E;&amp;#x3059;\n&amp;#x30FB;&amp;#x5404;&amp;#x30D5;&amp;#x30A7;&amp;#x30FC;&amp;#x30BA;&amp;#x3067;&amp;#x30A8;&amp;#x30E9;&amp;#x30FC;&amp;#x3092;return&amp;#x3059;&amp;#x308B;&amp;#x3068;&amp;#x3001;&amp;#x305D;&amp;#x3053;&amp;#x3067;response&amp;#x3092;&amp;#x3082;&amp;#x3052;&amp;#x3063;&amp;#x3066;logging&amp;#x306B;&amp;#x884C;&amp;#x304D;&amp;#x307E;&amp;#x3059;\n
  • &amp;#x30FB;PerlHandler &amp;#x2192; PerlResponseHandler\n&amp;#x30FB;PerlResponseHandler ModPerl::Registry &amp;#x306F;&amp;#x3053;&amp;#x308C;&amp;#x3067;&amp;#x3059;\n&amp;#x30FB;PerlMapToStorageHandler &amp;#x306F; mod_perl1 &amp;#x306E; PerlTransHandler &amp;#x306E;&amp;#x4ED5;&amp;#x4E8B;&amp;#x3092;&amp;#x5206;&amp;#x696D;&amp;#x3059;&amp;#x308B;&amp;#x305F;&amp;#x3081;&amp;#x306B;&amp;#x51FA;&amp;#x6765;&amp;#x305F;&amp;#x65B0;&amp;#x3057;&amp;#x3044;&amp;#x30D5;&amp;#x30A7;&amp;#x30FC;&amp;#x30BA;\n
  • &amp;#x30FB;&amp;#x30D5;&amp;#x30A3;&amp;#x30EB;&amp;#x30BF;&amp;#x306B;&amp;#x3064;&amp;#x3044;&amp;#x3066;&amp;#x306F;&amp;#x5272;&amp;#x611B;&amp;#x3057;&amp;#x307E;&amp;#x3059;\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • &amp;#x30FB;&amp;#x4ECA;&amp;#x56DE;&amp;#x306F;PerlProcessConnectionHandler&amp;#x306B;&amp;#x30D5;&amp;#x30A9;&amp;#x30FC;&amp;#x30AB;&amp;#x30B9;&amp;#x3092;&amp;#x5F53;&amp;#x3066;&amp;#x307E;&amp;#x3059;\n&amp;#x30FB;&amp;#x3053;&amp;#x308C;&amp;#x3089;&amp;#x3092;&amp;#x3072;&amp;#x3063;&amp;#x304F;&amp;#x308B;&amp;#x3081;&amp;#x3066;Connection&amp;#x30D5;&amp;#x30A7;&amp;#x30FC;&amp;#x30BA;&amp;#x3068;&amp;#x8A00;&amp;#x3063;&amp;#x305F;&amp;#x308A;&amp;#x3059;&amp;#x308B;&amp;#x3053;&amp;#x3068;&amp;#x3082;&amp;#x3042;&amp;#x308A;&amp;#x307E;&amp;#x3059;\n
  • \n
  • \n
  • &amp;#x30FB;Apache2 Connection &amp;#x3067;&amp;#x52D5;&amp;#x304F;&amp;#x3057;&amp;#x3002;Experimental&amp;#x3060;&amp;#x3063;&amp;#x3066;&amp;#x53E4;&amp;#x3044;&amp;#x8CC7;&amp;#x6599;&amp;#x306B;&amp;#x306F;&amp;#x66F8;&amp;#x304B;&amp;#x308C;&amp;#x3066;&amp;#x3044;&amp;#x305F;&amp;#x3051;&amp;#x3069;\n&amp;#x30FB;AnyEvent&amp;#x30D9;&amp;#x30FC;&amp;#x30B9;&amp;#x306E;&amp;#x3082;&amp;#x306E;&amp;#x306F;&amp;#x6700;&amp;#x65B0;&amp;#x306E;&amp;#x306B;&amp;#x3082;&amp;#x7121;&amp;#x3044;&amp;#x3088;&amp;#x3046;&amp;#x3067;&amp;#x3059;&amp;#x304C;&amp;#x3001;&amp;#x4F5C;&amp;#x308B;&amp;#x3068;&amp;#x9762;&amp;#x767D;&amp;#x3044;&amp;#x304B;&amp;#x3082;&amp;#x3057;&amp;#x308C;&amp;#x307E;&amp;#x305B;&amp;#x3093;&amp;#x306D;\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • モダンmod_perl入門 #yapcasia

    1. 1. モダンmod_perl入門 (Modern mod_perl Guide) 尾形 鉄次 (OGATA Tetsuji) Twitter: @xtetsuji 2012/09/29 YAPC::Asia Tokyo 2012
    2. 2. Attention for audience• This slide is mainly written by Japanese, and few English. In the future, I will write and share this slide of English version, perhaps.• I speach by Japanese language.• If you do not known Japanese language, please fun and feel from some Perl code and few English description on this slide.
    3. 3. Self-introduction
    4. 4. 自己紹介• 尾形 鉄次 (OGATA Tetsuji)• Twitter: @xtetsuji• Blog: http://post.tetsuji.jp/• SlideShare: http://www.slideshare.net/xtetsuji• よく行く: Hokkaido.pm, Hachioji.pm• 得意技: mod_perl (他はよく知らない)
    5. 5. 所属紹介• 株式会社fonfun(フォンファン) http://www.fonfun.co.jp/ • 主力製品:リモートメール http://rmail.jp/
    6. 6. Agenda
    7. 7. Agenda• About mod_perl basics• mod_perl handler basics• Refactoring mod_rewrite• mod_perl meets PHP• Apache worker MPM and Perl ithreads• compare mod_{lang} families• In future my activities
    8. 8. If time is left• Compare with others• Connection cycle: Let’s make SMTP Server by mod_perl• Other topics
    9. 9. In the first
    10. 10. Respect for ... モダンPerl入門(翔泳社 2009; http://books.shoeisha.co.jp/book/b73388.html )
    11. 11. 参考文献• 洋書になりますが、mod_perlを勉強する 上で役立つ3冊 • Practical mod_perl (Orelly 2003; http://modperlbook.org/) • The mod_perl Developer’s Cookbook (Sams Publishing 2002; http://www.modperlcookbook.org/) • mod_perl2 User’s Guide (Onyx Neon 2007; http://modperl2book.org/)
    12. 12. About mod_perl basics
    13. 13. History of mod_perl• mod_perl1 first public release: 1996/3/25 (see: http://perl.apache.org/dist/mod_perl-1.0-current/Changes)• mod_perl2 first public release: 2002/4/6 (see: http://perl.apache.org/dist/mod_perl-2.0-current/Changes)
    14. 14. Perl CGI の高速化• mod_perl1 # ↓Apache Configurations AddHandler perl-script .pl PerlHandler Apache::Registry• mod_perl2 AddHandler perl-script .pl PerlResponseHandler ModPerl::RegistryPrefork• こう書くことで、拡張子”.pl”のPerl CGI が高速化する (Registry→PerlRunでも可)
    15. 15. Perl CGIの高速化• CGI.pm、CGI::Simple 等は内部で mod_perl高速化環境をサポート済み• とはいえ永続環境なので、グローバル 変数の扱い等注意が必要 →モダンPerlなコードを書こう
    16. 16. mod_perlって何?• Perl CGIの高速化?→副次的な効果• 本当は「Apacheがモジュールで提供す る機能をC言語を使わずPerlで書ける ようにしたもの」がmod_perl• C言語が読み書きできない俺歓喜
    17. 17. About mod_perl basics• Perl CGIの高速化についてはだいぶ割愛 させていたきますが、世間に出回って いる間違った知識の是正だけはどこか でしたい• 後はApacheのmod_perl拡張ハンドラを 読み書きして楽しみましょう
    18. 18. mod_perl handler basics
    19. 19. mod_perl essence is extension of Apache• mod_perl の Perl CGI高速化環境では、 HTTPリクエストを受けてレスポンスを 返すことが出来るのは周知の通り• mod_perlはHTTPレスポンスを返すだけ でなく、その前処理や後処理もできる
    20. 20. Apache internal• MPMは多く使われているpreforkを想定• 親プロセスを起動すると、設定に従って 子プロセスを設定の数だけ起動(prefork)• 各子プロセスはHTTPリクエストを待つ• では子プロセスごとのHTTP処理は...
    21. 21. Apache internal• リクエストを受ける• ヘッダを解析する• 必要に応じてURLを変換したり、DocumentRootを手がかりに実パスを 割り出す• アクセス制御、認証、承認(BASIC認証など)• MIMEタイプを考える• レスポンスを出す(静的ファイル、プログラム出力)• ログ(アクセスログ、エラーログ)を出力する• 次のリクエストを待つ
    22. 22. Apache internal• 各処理を行っている部分にはフックが あって、ここに各種処理を挟むことが 可能 → Apache Module(mod_xxxxxx)• Apache Module でできることを Perl でできるようにしたもの → mod_perl
    23. 23. Apache/mod_perl process phase• 各フックがある部分: 「(処理)フェーズ」• リクエスト待ち状態から各フェーズを 一巡するので、全体を 「リクエストサイクル」と呼びます
    24. 24. Phase of mod_perl1 PerlChildInitHandler PerlPostReadRequestHandler PerlInitHandler PerlTransHandler PerlHeaderParserHandler PerlAccessHandler PerlAuthenHandler PerlAuthzHandler PerlTypeHandler PerlFixupHandler PerlFixupHandler PerlHandler PerlLogHandler PerlCleanupHandler PerlChildExitHandler ※一部省略があります。詳しくは以下を参照 http://perl.apache.org/docs/1.0/guide/config.html#toc_Perl_Handlers
    25. 25. Phase of mod_perl1 ※「Practical mod_perl」より抜粋
    26. 26. Phase of mod_perl2 PerlChildInitHandler PerlPostReadRequestHandler PerlInitHandler PerlTransHandler PerlMapToStorageHandler PerlHeaderParserHandler PerlAccessHandler PerlAuthenHandler PerlAuthzHandler PerlTypeHandler PerlFixupHandler PerlFixupHandler PerlResponseHandler PerlLogHandler PerlCleanupHandler PerlChildExitHandler ※かなり省略があります。詳しくは以下を参照 http://perl.apache.org/docs/2.0/user/config/config.html
    27. 27. Phase of mod_perl2 ※「Practical mod_perl」より抜粋
    28. 28. first mod_perl1 handler package MyApache::Hello; use strict; use warnings; use Apache::Constants qw(OK); sub handler { my $r = shift; # "Apache" object $r->send_http_header(text/plain); $r->print("Hello! mod_perl1.n"); return OK; } 1;
    29. 29. first mod_perl2 handlerpackage MyApache2::Hello;use strict;use warnings;use Apache2::RequestRec (); # for $r->content_type()use Apache2::RequestIO (); # for $r->print()use Apache2::Const -compile => qw(OK);sub handler { my $r = shift; # "Apache2::RequestRec" object $r->content_type(text/plain); $r->print("Hello! mod_perl2.n"); return Apache2::Const::OK;}1;
    30. 30. Apache{1,2} configs # Apache1 <Location /> SetHandler perl-script PerlHandler MyApache1::Hello </Location> # Apache2 <Location /> SetHandler modperl PerlResponseHandler MyApache2::Hello </Location>
    31. 31. first mod_perl handler• 全ては sub handler と $r の受け取りから • これはどの処理フェーズでも同様• mod_perl2 では $r のメソッド群が各種 別パッケージで管理されているため、 メソッドによって事前に適切な Apache2::* を use しておく必要がある
    32. 32. first mod_perl handler• PerlHandler / PerlResponseHandler にハン ドラをセットしておけば、全てのファ イルの処理をフックできるので、*.html ファイル等をあたかも透過的に処理す ることができる → 絵文字処理など
    33. 33. Refactoringmod_rewrite
    34. 34. About mod_rewrite• URLを書き換えるApacheモジュール• 「Apacheのスイス製アーミーナイフ」• 簡単なコードでURL書き換えが可能だ けれど、数十行も書けば魔窟の完成• 黒魔術と呼ばれる理由
    35. 35. Refactoring mod_rewrite• mod_perl では PerlTransHandler という URL を書き換えるフェーズを用意して いる• ここに URL 変換処理を挟める
    36. 36. Apache1 URI Transpackage MyApache1::Trans;use strict;use warnings;use Apache::Constants qw(DECLINED);sub handler { my $r = shift; my $uri = $r->uri(); # e.g. "/path/to/foo.html" ### ... modify $uri ... $r->uri($uri); return DECLINED; # I tell a lie that I do nothing.}1;
    37. 37. Apache2 URI Transpackage MyApache2::Trans;use strict;use warnings;use Apache2::RequestRec (); # for $r->uri()use Apache2::Const -compile => qw(DECLINED);sub handler { my $r = shift; my $uri = $r->uri(); # e.g. "/path/to/foo.html" ### ... modify $uri ... $r->uri($uri); # set $uri return Apache2::Const::DECLINED; # I tell a lie that I do nothing.}1;
    38. 38. Apache{1,2} configs # Apache1 # e.g. In <VirtualHost> Directive PerlTransHandler MyApache1::Trans # Apache2 # e.g. In <VirtualHost> Directive PerlTransHandler MyApache2::Trans
    39. 39. mod_perl URI Transpros than mod_rewrite• mod_rewriteに比べて可読性が高くなる• DBを引いたりmemcachedにアクセスし たりPerlで出来ることは何でもできる
    40. 40. mod_perl URI Transcons than mod_rewrite• 複数のファイル管理が必要となる(*.pm)• Perl/mod_perlが分からない担当者への 引き継ぎが難しくなる• Directory Context(<Location>, .htaccess) に書かれたmod_rewrite設定の場合は、 別途ケアが必要なケースもある
    41. 41. mod_perl meets PHP
    42. 42. PHP pathetic story of Perl Monger• 誰かが発注したアプリがPHP製で、既に 勝手に納品しちゃっている• 蓋を開けると実装とかがテキトウ過ぎ• 契約や諸々の理由で手を入れられない• 運用担当でPerlしか知らない俺がPHPの デバッグとか…
    43. 43. mod_perl meets PHP• PHPが実行される前後にmod_perlで何か フックを差し込めないか • PHP処理前に認証・許可処理 • PHP処理後に出力をフィルタ…等々
    44. 44. Review request phase
    45. 45. Access/Authen/Authz and PHP• session_*()の使い方等がダメなケースで は、PHP中のそれらのコードを除去して mod_perlのAccess/Authen/Authzフェーズ で対処するケースも考えられる• Cookie、X-UP-Subno等のRequest Header は全て読める → 認証を肩代わりできる
    46. 46. package MyApache2::Auth;use strict;use warnings;# $r->headers_in() and $r->headers_out() returns APR::Tableuse APR::Table ();use Apache2::RequestRec ();use Apache2::Const -compile => qw(OK REDIRECT);sub handler { my $r = shift; my $cookie = $r->headers_in->get(Cookie); # raw cookie my $x_up_subno = $r->headers_in->get(X-UP-Subno); my ($is_success, $location, $set_cookie); ### ### ... modify and analyze this session information ... ### if ( $is_success ) { $r->headers_out->set(Set-Cookie => $set_cookie); return Apache2::Const::OK; } else { $r->headers_out->set(Location => $location); $r->err_headers_out->set(Location => $location); return Apache2::Const::REDIRECT; }} # e.g. In <VirtualHost> Directive1; PerlAccessHandler MyApache2::Auth
    47. 47. Request output filter and PHP• PHPの出力をフィルタする• Apache2のネイティブフィルタなので、 PHPの ob_*() (output buffering) 等の設定 に一切影響されない• 応用例: 絵文字変換、PHPで書ききれな い部分を後で置換する、等々
    48. 48. Requets output filter practice• Filter の場合 sub handler { ... } は $r (Request Object)ではなく、 $f (Filter Object) を第一引数に受け取る• PerlOutputFilterHandler ディレクティブ• 今回は改行を除去する簡単なサンプル を紹介
    49. 49. package MyApache2::FilterObfuscate;use APR::Table ();use Apache2::Filter ();use Apache2::RequestRec ();use Apache2::Const -compile => qw(OK);my $READ_CHUNK_LENGTH = 2048;sub handler { my $f = shift; # $f is "Apache2::Filter" object ### If filter is chained, this filter is first? unless ($f->ctx) { $f->r->headers_out->unset(Content-Length); $f->ctx(1); } while ($f->read(my $buffer, $READ_CHUNK_LENGTH)) { $buffer =~ s/[rn]//g; $f->print($buffer); } return Apache2::Const::OK;}1; # e.g. In <VirtualHost> Directive <FilesMatch “.*(html?|php)$”> PerlOutputFilterHandler MyApache2::FilterObfuscate </FilesMatch>
    50. 50. PHP and Perl are friend• Apacheの上でPHPとPerlは友達!• 他にも各種フックを使ってmod_perlは PHPを助けることができる• 可能性は無限大
    51. 51. Apache worker MPM and Perl ithreads
    52. 52. Apache worker MPM and Perl ithreads• Apache worker MPM: スレッド(pthread) とプロセスのハイブリット動作• Perl ithreds: 嫌われ者 • 同時並行処理するならParallel::Prefork 等やAnyEventを使うのが今のPerl流儀
    53. 53. スレッドのメリット• 各リクエストフェーズ間で変数共有が 可能 (poor man’s memcached?)• 何か人とは違う事をしてるワクワク感
    54. 54. スレッドのデメリット• Perl ithreadsが安定していない• 各スレッド毎にインタープリタプール を作成する設計上、preforkとコストは それほど変わらない• スレッドセーフを意識する必要がある
    55. 55. Instruction worker MPM & mod_perl• worker MPM上でのmod_perlのノウハウ は特に少ないのでハマると危険• Perlのスレッドは不安定である事を心得 た上で、複雑な事はさせてはいけない
    56. 56. Queue server by mod_perl2 thread• 今回はスレッドの変数共有を利用した mod_perl2の文字列Queueサーバを実演• “POST /” でRequest BodyをQueueing、• “GET /” でQueueをPickup
    57. 57. Queue server by mod_perl2 thread (1)package My::Queue;use strict;use warnings;use threads;use threads::shared;my @queue :shared;sub push_queue { my $value = shift; return 0 if !defined $value; push @queue, $value; return 1;}sub shift_queue { return shift @queue}1;
    58. 58. Queue server by mod_perl2 thread (2)package MyApache2::ThreadQueue;use strict;use warnings;use threads;use Apache2::RequestRec ();use Apache2::RequestIO ();use Apache2::Const -compile => qw(OK HTTP_METHOD_NOT_ALLOWED);use My::Queue;my $READ_CHUNK_LENGH = 2048;###### ... following sub handler { ... } ...###
    59. 59. Queue server by mod_perl2 thread (3)### continuedsub handler { my $r = shift; if ( $r->method eq POST ) { my $value; while ( $r->read(my $buf, $READ_CHUNK_LENGH) ) { $value .= $buf; } My::Queue::push_queue($value); $r->content_type(text/plain); $r->print(Queued); return Apache2::Const::OK; } elsif ( $r->method eq GET ) { my $retval = My::Queue::shift_queue(); $r->content_type(text/plain); $r->print($retval); return Apache2::Const::OK; } else { return Apache2::Const::HTTP_METHOD_NOT_ALLOWED; }}1;
    60. 60. worker MPM andperl ithreads practice• 複雑な事はさせてはいけない• 複雑な事をさせる場合には十分試験を• 大事なことなので(ry• 前出のQueue serverは100KB程度の文字 列の入出力を10K/minさせても問題無し
    61. 61. compare mod_{lang} families
    62. 62. mod_{lang} (1)• mod_perl: 最も歴史が古いものの一つ• mod_ruby: 開発停滞状態→mod_mruby• mod_python: 開発停滞状態• mod_lua: Apache2.4からコアモジュール• mod_mruby: 2012年4月に登場し活発
    63. 63. mod_{lang} (2)• mod_wsgi: Python WSGI 実装• mod_php: いわゆるPHP • こちらは今までの意味でApacheを 「拡張」するものではない• 他にもたくさんmod_{lang}はあるらしい
    64. 64. Benchmark http://blog.matsumoto-r.jp/?p=2669 より
    65. 65. Benchmark http://blog.matsumoto-r.jp/?p=2669 より
    66. 66. Benchmark• Perl CGI高速化環境(PerlRun, Registry)の 場合はmtime(ファイルの最終更新日時) を都度見るので、statシステムコールの コストが無視できない• mod_perlネイティブハンドラで勝負!
    67. 67. Benchmark• 実際、mod_perlネイティブハンドラで 同等のベンチマークを行うと About 7000 Response/secとのこと (Thanks @matsumotory)• Yet another perl5 implement で mod_*perl を作ると良い勝負ができるかな
    68. 68. In future my activities
    69. 69. In future my activities• mod_perlの役立つ情報やコードを公開 していきたい• mod_perlで困っている人を助けたい
    70. 70. In future my activities• 今後もmod_perl界隈を盛り上げたい• Twitterアカウント作った @mod_perl_info• ウェブサイトも作成中(未完成) http://modperl.info/• 詳細、割愛した部分の続きはどこかで
    71. 71. Timeup?
    72. 72. Questions?
    73. 73. ☆Service Slides☆
    74. 74. Compare with others
    75. 75. Compare with others• Pure CGI• FastCGI• PSGI/Plack, WAF
    76. 76. mod_perl and pure CGI• パフォーマンスを要求しなければ良い• Apache以外のウェブサーバでも使える• レンタルサーバ等、mod_perlすら使え ない環境は未だに多い
    77. 77. mod_perl and FastCGI• どちらも同じ永続環境、適材適所• Apache拡張ならmod_perl、CGIの高速化 のみならFastCGI• mod_perlの場合Apacheプロセス自身が 肥大化していくことを嫌う向きもある
    78. 78. mod_perl and PSGI/Plack, WAF• モダンなウェブアプリを今から書くの であればPlackベースのWAFを選ぼう• Apacheを拡張して他の言語との連携や Apache自体の動作を拡張できるのは mod_perlの面目躍如
    79. 79. Should you choice mod_perl?• Apacheという枠の中ではあるものの、 mod_perlの可能性はとても広い• パフォーマンス、移植性、様々な要素 を検討して、mod_perlを使うか考える• 既にあるApache上のレガシーコードを リファクタリングするなら良い選択
    80. 80. Connection cycle: Let’s make SMTPServer by mod_perl
    81. 81. Connection cycle• HTTP以外のサーバを書きたい• Apacheと同様の安定性が欲しい• Apache2/mod_perl2では、Connectionを HTTP以外の自前のものに書き換える事 ができる (e.g. mod_ssl)
    82. 82. AboutConnection Cycle PerlPreConnectionHandler PerlProcessConnectionHandler ※「Practical mod_perl」より抜粋
    83. 83. Why I want to write SMTP server by perl• DB引きたい• 絵文字処理したい• 通常のMTA(Sendmail/qmail/Postfix等)の pipeではスケールできない
    84. 84. Qpsmtpd• http://smtpd.develooper.com/• 実際に私(会社)もmod_perl2 Connection cycleでSMTPサーバを実装してみたもの の、既にPerl界隈にはQpsmtpdという MTAがある
    85. 85. Qpsmtpd has some Engine=Transport• pipe (CGI like)• fork-server• prefork-server• Apache (Apache::Qpsmtpd)• async (Danga::Socket base)
    86. 86. Qpsmtpd’s Apache::Qpsmtpd• Apache2 / mod_perl2 の Connection cycle の良い応用例• これを見るとApache2をEngineとして MTAを作る方法が良く分かる
    87. 87. Other topics
    88. 88. Test of mod_perl handler• 「モダンPerl入門」に詳しく書いてある• Apache2::FakeRequestを使って偽物の$r を作ってハンドラをテストできる• 処理単位のテストはTest::More等で• 詳しくは割愛、もしくは上述の書籍を
    89. 89. nginx: HttpPerlModulehttp://wiki.nginx.org/HttpPerlModule
    90. 90. nginx: HttpPerlModule• 構文や考え方がmod_perl1と酷似 →mod_perlの知識を流用可能• ただしイベント駆動サーバならではの 各種制限もあるので注意• 世間での応用例も少し出てきている• 以前はEmbeddedPerlModuleという 名前だった(1.0→1.2で名称変更?)
    91. 91. nginx:HttpPerlModulepackage hello;use nginx;sub handler { my $r = shift; $r->send_http_header("text/html"); return OK if $r->header_only; $r->print("hello!n<br/>"); $r->rflush; if (-f $r->filename or -d _) { $r->print($r->uri, " exists!n"); } return OK;}1;__END__ http://wiki.nginx.org/HttpPerlModule より
    92. 92. nginx: HttpPerlModule• mod_perl2ではなくmod_perl1の構文の 影響を強く受けている ($r->send_http_headers()等に見られる)• nginx設定ファイルの書き方については 割愛→前述のWikiに詳細がある
    93. 93. 割愛したこと• Perl CGIの高速化環境の詳細• Apache2.4環境でのmod_perl→現時点 (2012/09)で正式にサポートしていない• Apache2.4 event MPM環境での mod_perl→上記同様
    94. 94. これからのApache• Apache2.4でmod_perlがサポートされた ら、event MPM上でmod_perl動かしたい• Apacheはこれからも進化していきます• mod_lua, mod_sedがApache2.4でコアモ ジュール入り、しかしExperimental扱い
    95. 95. Questions?
    96. 96. ご清聴ありがとうございました
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×