#!/usr/bin/perl use strict; use warnings; { my $flg; { my $cnt = 1 if ( $flg ); $cnt++; print "Content-type: text/plain\n\n"; print join( ', ', $cnt, $$, \$cnt ); } } 1; 上記のような CGI を mod_perl(ModPerl::Registry)上で動かすと、Apacheのプロセス毎に $cnt がカウントアップされます。 なぜでしょう??? 誰か教えてください。 $cnt はレキシカルスコープなはずですよね。スコープが外れた {} の後で $cnt を使うと怒られます。なのに、なぜかグローバル変数のように共有されてしまいます。 そもそも、my $cnt = 1 if ( $flg ); はどのように動作するのでしょう
大量にアクセスがあってMaxClientを大きく設定したい場合、Apacheの1プロセスあたりのメモリを少なくするのが重要。当然アプリ側で大きなライブラリを読み込まずに画像の変換はGearmandにタスクとして投げたりとかの工夫するのも有効だが、fork元になるApacheの親プロセスと子プロセス間でできる限りCopy on Writeな共有メモリを増やすのも有効。 その辺の詳しい仕組み等の話はnaoyaさんがd:id:naoya:20080212:1202830671でしてるのでそこを参考に。linuxカーネルまわりの仕組みって楽しいよね。会社の案件ではFreeBSDサーバーも結構あるんだけどFreeBSDではどうなるのかは知らない。 で、社内にXenなテストサーバーがあるのでまっさらな環境で色々実験してみた。・・・過程を全部書こうとしたら長くなったので省略。地味にpsしたり/proc/
だらだらと3日にわたって書いてきましたが,明日から遅めのお盆休みになるのでまとめをメモ書きしておきます。 worker MPM での mod_perl は Perl の ithread を使っている httpd のスレッドプールとは独立して Perl インタプリタプールが存在する Perl インタプリタプールの最大インタプリタ数などは設定で変更可能 デフォルトで最大 5(少ない!) インタプリタプールはインタプリタのステート保持構造体のプールであり,インタプリタスレッドのプールではない(実行時アタッチ)←ちょっと推測 だから httpd のスレッドプールのスレッド数より多くも少なくも設定できる インタプリタ数が足りなくなったときは空きがでるまでブロックする Perl ithread では変数は TLS (スレッド間で独立したロケーション)に保持され,基本的にスレッドセーフ 他インタプリタス
daily dayflower などの情報をみて worker MPM な Apache を利用しても、同時に利用可能な Perlインタプリタ(mod_perlプロセス) は PerlInterpMax に制限されるように思っていました。デフォルトではこの値は 5 であり、一見少なく感じられます。 サーバDoS事件 ご存じのとおり本 blog.abk.nu サーバは、以前まで「データベースに接続できないエラー」を吐いてブログが表示されないことが多々発生していました*1。以前の設定値は次のとおりです。 mod_perl : PerlInterpMax 5 PostgreSQL : max_connections = 15 これでも、PostgreSQLへのコネクションが足りなくなりエラーとなっていました。PostgreSQLへのコネクションを保持するデーモンは adiary の他にありません
前々回も書きましたが,worker MPM で mod_perl を使うと,インタプリタプールなるものが作成されます。このインタプリタプールというのはまさに Apache におけるプロセスプール(prefork MPM の場合)やスレッドプール(worker MPM の場合)の Perl インタプリタ版のようなものです。 このインタプリタプールでの PerlInterpMax(総数の最大)はデフォルトで 5 になっています。ですから,「prefork MPM から worker MPM にしたらメモリ消費量がガツンと減ったぜ!httpd の thread 数 150 でぶんまわしてるのに!スレッドマンセー!」とぬか喜びしていると,実は Perl は並列に 5 つしか走っていなかった,ということがありえます。 2007/09/27 追記。adiary 作者さんからトラバいただきました(⇒Pe
Apache::Test事始め 年末前後からApache::Testで真面目にテストを書き始めている。 ところが全くドキュメントがないんだね。いや、あるんだけど、携帯の機能を使いたいだけなのにあの厚いマニュアル読むの?みたいな感じで。まぁというわけでとにかくざくざくっとドキュメント読んでテスト書いてたらようやくなんとなく分かってきた。この間ある程度他人にも説明できたので自信ついたしw Apache::Testはmod_perlハンドラをテストするときに使う。ディストリビューション等でmod_perlをテストしようと思うとApache自体を立ち上げたりなんだりしなければいけなくて「一体どうテストすればいいんじゃ?!」となりがちだが、Apache::Testを使うと、テスト用httpd.confの生成テスト用のapacheの起動/停止mod_perlハンドラ上で動かしたTest::More等の
文章を修正しました。パッチの変更はありません。 Apache2::Reloadは、対象パッケージのシンボルを全て削除した上でリロードするようになっています。しかし、対象パッケージの外部から動的に定義されているシンボルを削除してしまうと、復元することができなくなってしまいます。DBIx::Classとか他にも色々、Class::Data::Inheritableのようなものを使っている場合は大抵この現象が起きます。 そこでApache2::Reloadに当てる動的パッチを作ってみました。このパッチを当てると、シンボルを全て削除してしまうModPerl::Util::unload_package_ppは使われなくなり、%INCからモジュール名のみが削除されるようになります。 PerlModule Apache2::Reload PerlInitHandler Apache2::Reload <
CGI 時代では,たとえばメールを送るなど時間がかかる処理を行う時は fork() を使っていました。子プロセスでメール送信,親プロセスでレスポンスを返す,とやると,ユーザはメールが実際に送られるかどうかに関わらず ASAP でレスポンスを受け取ることができました,たしか(\*STDOUT を close したりとかいろいろあった気もするけど)。 では mod_perl(2) ではどうなのか。ベストプラクティスがわかりません。 Cleanup ハンドラを登録してそこでやる threads を使う(prefork MPM だとうまくいかない気がする…ハンドラ終了時に thread が殺されそうな予感→forks 使えばいいのかな?) 意地でも fork を使う*1 時間がかかる処理はデーモンを書き起こしてレスポンスハンドラから UNIX ソケット等で接続(笑 この中だと1番目なのですかねぇ。
mod_perl 2.0 のサーバ起動にまつわる文書を読み込んでいました。 サーバスタートアップスクリプトは,1.0 時代のドキュメントでは「PerlRequire」記述子で読み込むように書かれていることが多いが,実行される時点が中途半端。なので,PerlPostConfigRequire を使う方が吉。もし設定ファイル自体で Perl の機能を利用しているのであれば(普通そこまでコアなことやらなくて済むんだけど),PerlConfigRequire を使うとサーバ設定フェイズ(すなわちかなり早い段階)で実行される。 Apache 2.x では,graceful restart がうまくいくことの確証を得るために,一度サーバ設定フェイズが終わると,Apache 自身を再起動する。ということは,サーバ起動時に,スタートアップスクリプト等は 2 回実行される。このことで困るってことはたいていな
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く