blog20100901

2013/08/20 - プログラミング言語 Perl にまつわる etc. - Perl monger
参考 : perldoc, perldoc.jp, search.cpan.org, perldoc.perl.org ...
「 初めての Perl 第 6 版 」(オライリー・ジャパン発行 ISBN978-4-87311-567-2) 」
「 続・初めての Perl 改訂版 」(オライリー・ジャパン発行 ISBN4-87311-305-9) 」
「 Effective Perl 第 2 版 」(翔泳社発行 ISBN978-4-7981-3981-4) 」 ... etc,.

Perl Perl_7 mod_perl 翻訳 Web Server

Perl mp2 翻訳 サーバの制御と監視 (d213)

目次 - Perl Index


Theme



Perl について、復習を兼ねて断片的な情報を掲載して行く連載その d213 回。

今回は、mod_perl「 Documentation / General Documentation / Part IV: Server Administration / Controlling and Monitoring the Server 」を翻訳して確認します。

正確な内容は 原文 を確認してください。誤解や誤訳がある場合はご指摘ください。




説明 : Description



Covers techniques to restart mod_perl enabled Apache, SUID scripts, monitoring, and other maintenance chores, as well as some specific setups.

mod_perl が有効化された Apache のリスタート, SUID スクリプト, モニタリング, それから他のメンテナンス作業, およびいくつか特定のセットアップのテクニックをカバーします.


リスタートのテクニック : Restarting Techniques



All of these techniques require that you know the server process id (PID). The easiest way to find the PID is to look it up in the httpd.pid file. It's easy to discover where to look, by looking in the httpd.conf file. Open the file and locate the entry PidFile. Here is the line from one of my own httpd.conf files:

これらのテクニックはすべてあなたがサーバプロセス id (PID) を知っていることを要求します. PID を見つけるもっとも簡単な方法は httpd.pid ファイルを検索することです. httpd.conf を確認することで, どこを見ればよいかを簡単に発見できます. そのファイル (# httpd.conf) を開いてエントリ PidFile を見つけます. こちらは私独自の httpd.conf ファイルからの行です:

PidFile /usr/local/var/httpd_perl/run/httpd.pid

As you see, with my configuration the file is /usr/local/var/httpd_perl/run/httpd.pid.

あなたがご覧の通り, 私の構成でそのファイルは /usr/local/var/httpd_perl/run/httpd.pid です.
Another way is to use the ps and grep utilities. Assuming that the binary is called httpd_perl, we would do:

他の方法は ps と grep ユーティリティを使うことです. そのバイナリが httpd_perl と呼ばれると想定すると, 私たちはこれを行います:

% ps auxc | grep httpd_perl

or maybe:

またはおそらく:

% ps -ef | grep httpd_perl

This will produce a list of all the httpd_perl (parent and children) processes. You are looking for the parent process. If you run your server as root, you will easily locate it since it belongs to root. If you run the server as some other user (when you don't have root access, the processes will belong to that user unless defined differently in httpd.conf. It's still easy to find which is the parent--usually it's the process with the smallest PID.

これはすべての httpd_perl (parent (# 親) と children (# 子)) プロセスのリストを作成します. あなたは parent プロセスを探します. もしあなたがあなたのサーバを root として実行している場合, それは root に属しているのであなたは簡単にそれを見つけることができます. もしあなたが他のユーザとしてサーバを実行している (あなたが root アクセスをもっていない) なら, そのプロセスは httpd.conf で別に定義されていない限りはそのユーザに属します. どれが parent かを見つけるのはまだ簡単です - 通常そのプロセスは最も小さい PID です.
You will see several httpd processes running on your system, but you should never need to send signals to any of them except the parent, whose pid is in the PidFile. There are three signals that you can send to the parent: SIGTERM, SIGHUP, and SIGUSR1.

あなたはあなたのシステム上でいくつかの httpd プロセスが走っているのを見るでしょうが, あなたは PidFile に pid がある, parent を除いたそれらのいずれにもシグナルを送る必要はありません. あなたが parent に送ることができる 3 つのシグナルがあります: SIGTERM, SIGHUP, それと SIGUSR1 です.
Some folks prefer to specify signals using numerical values, rather than using symbols. If you are looking for these, check out your kill(1) man page. My page points to /usr/include/linux/signal.h, the relevant entries are:

ある人々はシンボルを使うよりも, 数値を使ったシグナルの指定を好みます. あなたがそれらを探しているなら, あなたの kill(1) man ページをチェックしてください. 私のページは /usr/include/linux/signal.h を指していて, 関連するエントリはこれです:

#define SIGHUP 1 /* hangup, generated when terminal disconnects */
#define SIGKILL 9 /* last resort */
#define SIGTERM 15 /* software termination signal */
#define SIGUSR1 30 /* user defined signal 1 */

Note that to send these signals from the command line the SIG prefix must be omitted and under some operating systems they will need to be preceded by a minus sign, e.g. kill -15 or kill -TERM followed by the PID.

コマンドラインからこれらのシグナルを送信するためには SIG プレフィクスは省略しなければならず一部オペレーティングシステムのもとではマイナスサインによって先行される必要があることに注意してください, e.g. kill -15 や kill -TERM に続けて PID です.


サーバのストップとリスタート : Server Stopping and Restarting



We will concentrate here on the implications of sending TERM, HUP, and USR1 signals (as arguments to kill(1)) to a mod_perl enabled server. See http://www.apache.org/docs/stopping.html for documentation on the implications of sending these signals to a plain Apache server.

私たちはここで TERM, HUP, それから USR1 シグナルを (kill(1) への引数として) mod_perl が有効化されたサーバに送信する意味に集中します. プレーンな Apache サーバにこれらのシグナルを送る意味についてのドキュメンテーションは http://www.apache.org/docs/stopping.html を参照してください.


  • TERM Signal: Stop Now (TERM シグナル : 今すぐストップ)
    Sending the TERM signal to the parent causes it to immediately attempt to kill off all its children. Any requests in progress are terminated, and no further requests are served. This process may take quite a few seconds to complete. To stop a child, the parent sends it a SIGHUP signal. If that fails it sends another. If that fails it sends the SIGTERM signal, and as a last resort it sends the SIGKILL signal. For each failed attempt to kill a child it makes an entry in the error_log.

    parent に TERM シグナルを送信するとそれに起因してそのすべての children をキルオフしようとします. 進行中のリクエストは終了され, さらなるリクエストはサーブされません. このプロセスが完了するまでには数秒程度かかるかもしれません. child をストップするために, parent はそれに SIGHUP シグナルを送信します. もしそれが失敗すると他のものを送信します. もしそれが失敗すると SIGTERM シグナルを送信して, 最後の手段として SIGKILL シグナルを送信します. child の kill するための試みが失敗するたびにそれは error_log でエントリを作成します.
    When all the child processes were terminated, the parent itself exits and any open log files are closed. This is when all the accumulated END blocks, apart from the ones located in scripts running under Apache::Registry or Apache::PerlRun handlers. In the latter case, END blocks are executed after each request is served.

    すべての child プロセスが終了されたとき, parent 自身が終了しオープンしているすべてのログファイルが閉じられます. これはすべての蓄積された END ブロックの場合で, Apache::Registry や Apache::PerlRun ハンドラのもとで実行されているスクリプトにあるものは別です. 後者のケースで, END ブロックは各リクエストがサーブされた後で実行されます.


  • HUP Signal: Restart Now (HUP シグナル : 今すぐリスタート)
    Sending the HUP signal to the parent causes it to kill off its children as if the TERM signal had been sent, i.e. any requests in progress are terminated; but the parent does not exit. Instead, the parent re-reads its configuration files, spawns a new set of child processes and continues to serve requests. It is almost equivalent to stopping and then restarting the server.

    parent に HUP シグナルを送信するとそれに起因して TERM シグナルが送信されたかのようにその children をキルオフします, i.e. 進行中のすべてのリクエストは終了されます; しかし parent は終了しません. 代わりに, その parent は構成ファイルを再読込みして, child プロセスの新しいセットを生成しリクエストのサーブを継続します. これはサーバをストップしてリスタートすることとほとんど同等です.
    If the configuration files contain errors when restart is signaled, the parent will exit, so it is important to check the configuration files for errors before issuing a restart. How to perform the check will be covered shortly;

    リスタートがシグナルされたときに構成ファイルがエラーを含んでいた場合, その parent は終了します, ですからリスタートを発行する前に構成ファイルのエラーをチェックすることは重要です. どのようにチェックをするかはまもなくカバーします;
    Sometimes using this approach to restart mod_perl enabled Apache may cause the processes memory incremental growth after each restart. This happens when Perl code loaded in memory is not completely torn down, leading to a memory leak.

    mod_perl が有効な Apache をリスタートするためにこのアプローチを使うとリスタートのたびにプロセスメモリが増加する原因になる場合があります. これはメモリにロードされた Perl コードが完全に取り壊されなかった (# torn down) 場合に発生し, メモリリークにつながります.


  • USR1 Signal: Gracefully Restart Now (USR1 シグナル: 今すぐグレイスフルにリスタートする)
    The USR1 signal causes the parent process to advise the children to exit after serving their current requests, or to exit immediately if they're not serving a request. The parent re-reads its configuration files and re-opens its log files. As each child dies off the parent replaces it with a child from the new generation (the new children use the new configuration) and it begins serving new requests immediately.

    USR1 シグナルによって parent プロセスはその children にその現在のリクエストをセーブした後に終了する, またはそれらがリクエストをサーブしていないなら即時終了するようにアドバイスします. その parent は構成ファイルを再読込みしてログファイルを再オープンします. 各 child が die するとその parent はそれを新しい世代の child (その新しい children は新しい構成を使います) でリプレイスしてすぐに新しいリクエストのサーブをはじめます.
    The only difference between USR1 and HUP is that USR1 allows the children to complete any current requests prior to killing them off and there is no interruption in the services compared to the killing with HUP signal, where it might take a few seconds for a restart to get completed and there is no real service at this time.

    USR1 と HUP の唯一の違いは USR1 はその children がそれらがキルオフに先だって現在のリクエストを完了できるようにすることと HUP シグナルでのキルと比較してサービスの中断がないことです, そこ (# HUP シグナル) ではリスタートが完了されるまで数秒かかることがありそのときは実質的にサービスがありません.


By default, if a server is restarted (using kill -USR1 `cat logs/httpd.pid` or with the HUP signal), Perl scripts and modules are not reloaded. To reload PerlRequires, PerlModules, other use()'d modules and flush the Apache::Registry cache, use this directive in httpd.conf:

デフォルトでは, サーバがリスタートされた場合 (kill -USR1 `cat logs/httpd.pid` や HUP シグナルで), Perl スクリプトやモジュールはリロードされません. PerlRequires, PerlModules, その他 use() されたモジュールを読込んで Apache::Registry キャッシュをフラッシュするには, httpd.conf でこのディレクティブを使います:

PerlFreshRestart On

Make sure you read Evil things might happen when using PerlFreshRestart.

あなたは Evil things might happen when using PerlFreshRestart (PerlFreshRestart を使用すると邪悪なことが発生するかもしれない) を必ず読んでください.


Apache の終了と再起動のスピードアップ : Speeding up the Apache Termination and Restart



We've already mentioned that restart or termination can sometimes take quite a long time, (e.g. tens of seconds), for a mod_perl server. The reason for that is a call to the perl_destruct() Perl API function during the child exit phase. This will cause proper execution of END blocks found during server startup and will invoke the DESTROY method on global objects which are still alive.

私たちはすでに mod_perl サーバのリスタートや終了はかなり長い時間, (e.g. 数十秒), かかる場合があることを言及しました. その理由は child の終了フェーズの間に perl_destruct() Perl API 関数がコールされるためです. これによってサーバスタートアップ時に見つけられた END ブロックが適切に実行されてまだ生きているグローバルオブジェクトで DESTROY メソッドを呼びだします.
It is also possible that this operation may take a long time to finish, causing a long delay during a restart. Sometimes this will be followed by a series of messages appearing in the server error_log file, warning that certain child processes did not exit as expected. This happens when after a few attempts advising the child process to quit, the child is still in the middle of perl_destruct(), and a lethal KILL signal is sent, aborting any operation the child has happened to execute and brutally killing it.

このオペレーションがフィニッシュするために長い時間がかかり, リスタートの間に長い遅延が発生する可能性もあります. ときおりこれに続いてそのサーバの error_log ファイルで一連のメッセージが表示され, 特定の child プロセスが期待どおりに終了しなかったことを警告します. これは child プロセスに終了するように何度かアドバイスを試みた後で, まだその child が perl_destruct() の途中にあって, 致命的な KILL が送信され, child がたまたま実行していた操作を中断してそれを容赦なく kill したときに発生します.
If your code does not contain any END blocks or DESTROY methods which need to be run during child server shutdown, or may have these, but it's insignificant to execute them, this destruction can be avoided by setting the PERL_DESTRUCT_LEVEL environment variable to -1. For example add this setting to the httpd.conf file:

あなたのコードが child サーバがシャットダウンする間に実行する必要のある END ブロックや DESTROY メソッドを含んでいなかったり, それらを持っているが, それらの実行が重要ではない場合, このデストラクション (# 破壊) は PERL_DESTRUCT_LEVEL 環境変数を -1 にすることで回避できます. 例えばこの設定を httpd.conf ファイルに追加します:

PerlSetEnv PERL_DESTRUCT_LEVEL -1

What constitutes a significant cleanup? Any change of state outside of the current process that would not be handled by the operating system itself. So committing database transactions and removing the lock on some resource are significant operations, but closing an ordinary file isn't.

クリーンアップで重要なもの何でしょうか ? オペレーティングシステム自身では処理できないであろう現在のプロセスの外側の状態の変化です. ですからデータベーストランザクションのコミットや何らかのリソースでのロックの解除は重要な操作ですが, 普通のファイルを閉じることはそうではありません.


サーバの制御に apachectl を使う : Using apachectl to Control the Server



The Apache distribution comes with a script to control the server. It's called apachectl and it is installed into the same location as the httpd executable. We will assume for the sake of our examples that it's in /usr/local/sbin/httpd_perl/apachectl:

Apache ディストリビューションはサーバをコントロールするためのスクリプトがついてきます. それは apachectl と呼ばれそれは httpd 実行ファイルとおなじロケーションにインストールされます. 私たちは私たちの例のためにそれが /usr/local/sbin/httpd_perl/apachectl だと仮定します:
To start httpd_perl:

httpd_perl をスタートするには:

% /usr/local/sbin/httpd_perl/apachectl start

To stop httpd_perl:

httpd_perl をストップするには:

% /usr/local/sbin/httpd_perl/apachectl stop

To restart httpd_perl (if it is running, send SIGHUP; if it is not already running just start it):

httpd_perl をリスタートするには (もしそれが実行中なら, SIGHUP を送信します; それがまだ実行していないならそれをスタートするだけです):

% /usr/local/sbin/httpd_perl/apachectl restart

Do a graceful restart by sending a SIGUSR1, or start if not running:

SIGUSR1 を送信してグレイスフルリスタート, またはそれが実行されていなければスタートするには:

% /usr/local/sbin/httpd_perl/apachectl graceful

To do a configuration test:

構成テストを行うには:

% /usr/local/sbin/httpd_perl/apachectl configtest

Replace httpd_perl with httpd_docs in the above calls to control the httpd_docs server.

httpd_docs サーバをコントロールするには上記コールでの httpd_perl を httpd_docs でリプレイスしてください.
There are other options for apachectl, use the help option to see them all.

apachectl のための他のオプションがあります, それらすべてをみるには help オプションを使ってください.
It's important to remember that apachectl uses the PID file, which is specified by the PIDFILE directive in httpd.conf. If you delete the PID file by hand while the server is running, apachectl will be unable to stop or restart the server.

apachectl が PID ファイルを使うことを覚えておくことは重要です, それは httpd.conf の PIDFILE ディレクティブによって指定されます. もしあなたがサーバを実行している間に手動で PID ファイルを削除すると, apachectl はそのサーバのストップやリスタートができなくなります.


ライブプロダクションサーバ上での安全なコードのアップデート : Safe Code Updates on a Live Production Server



You have prepared a new version of code, uploaded it into a production server, restarted it and it doesn't work. What could be worse than that? You also cannot go back, because you have overwritten the good working code.

あなたは準備された新しいバージョンのコードをもち, それをプロダクションサーバにアップロードして, 再起動しましたがそれが機能しません. それよりも悪いことって何でしょう ? あなたは戻ることもできません, なぜならあなたがそのグッドに機能するコードの上書きをしたからです.
It's quite easy to prevent it, just don't overwrite the previous working files!

これを防ぐのはとても簡単で, 前に機能していたファイルを上書きしないだけです !
Personally I do all updates on the live server with the following sequence. Assume that the server root directory is /home/httpd/perl/rel. When I'm about to update the files I create a new directory /home/httpd/perl/beta, copy the old files from /home/httpd/perl/rel and update it with the new files. Then I do some last sanity checks (check file permissions are [read+executable], and run perl -c on the new modules to make sure there no errors in them). When I think I'm ready I do:

個人的に私はライブサーバでのすべてアップデートは次の順番で行います. そのサーバの root ディレクトリは /home/httpd/perl/rel だと仮定します. 私がそのファイルをアップデートしようとするとき私は新しいディレクトリ /home/httpd/perl/beta を作成し, /home/httpd/perl/rel からその古いファイルをコピーしてそれを新しいファイルでアップデートします. それから私は最後のサニティーチェック (# まともかどうかのチェック) をいくつか行います (ファイルのパーミッションが [read+executable] かをチェックし, 新しいモジュールでエラーがないことを確認するためにそれらで perl -c を実行します). 私が行う準備を私ができたと私がと思えたら:

% cd /home/httpd/perl
% mv rel old && mv beta rel && stop && sleep 3 && restart && err

Let me explain what this does.

これが何を行うのかを私に説明させてください.
Firstly, note that I put all the commands on one line, separated by &&, and only then press the Enter key. As I am working remotely, this ensures that if I suddenly lose my connection (sadly this happens sometimes) I won't leave the server down if only the stop command squeezed in. && also ensures that if any command fails, the rest won't be executed. I am using aliases (which I have already defined) to make the typing easier:

最初に, 私がすべてのコマンドを 1 行において, && で分割し, それから Enter キーを押しただけであることに注目してください. 私はリモートで作業しているので, もし私が突然私の接続を失った場合 (悲しいことにこれはときどき発生します) でも私が stop コマンドをねじ込んだがためにサーバがダウンしたままにならないことをこれが保証します. && はいずれかのコマンドが失敗した場合に, その残りが実行されないことも保証します. 私はそのタイピングを簡単にするためにエイリアス (私はそれをすでに定義してもっています) を使います:

% alias | grep apachectl
graceful /usr/local/apache/bin/apachectl graceful
rehup /usr/local/apache/sbin/apachectl restart
restart /usr/local/apache/bin/apachectl restart
start /usr/local/apache/bin/apachectl start
stop /usr/local/apache/bin/apachectl stop

% alias err
tail -f /usr/local/apache/logs/error_log

Taking the line apart piece by piece:

この行をひとつずつ分けてとります:

mv rel old &&

back up working directory to old

ワーキングディレクトリを old にバックアップします

mv beta rel &&

put the new one in its place

新しいものをその場所におきます

stop &&

stop the server

サーバをストップします

sleep 3 &&

give it a few seconds to shut down (it might take even longer)

シャットダウンのために数秒与えます (もっと長くかかるかもしれません)

restart &&

restart the server

サーバを restart します

err

view of the tail of the error_log file in order to see that everything is OK

すべてが OK であることをみるための error_log ファイルの末尾を眺める
apachectl generates the status messages a little too early (e.g. when you issue apachectl stop it says the server has been stopped, while in fact it's still running) so don't rely on it, rely on the error_log file instead.

apachectl はステータスメッセージの生成が少し早すぎるので (e.g. あなたが apachectl stop を発行したときそれはサーバがストップされたといいますが, 実際にはそれはまだ走っています) それに頼らず, 代わりに error_log ファイルを頼ります.
Also notice that I use restart and not just start. I do this because of Apache's potentially long stopping times (it depends on what you do with it of course!). If you use start and Apache hasn't yet released the port it's listening to, the start would fail and error_log would tell you that the port is in use, e.g.:

また私が start だけでなく restart を使っていることも注目してください. Apache が長い停止時間になる可能性があるので私はこれを行います (もちろんあなたがそれで何をするかによります!). もしあなたが start を使って Apache がリッスンしているポートをまだリリースしていなかった場合, その start は失敗し error_log がそのポートが使用中であることをあなたに伝えるはずです, e.g.:

Address already in use: make_sock: could not bind to port 8080

But if you use restart, it will wait for the server to quit and then will cleanly restart it.

しかしもしあなたが restart を使った場合, それはサーバが終了するの待ってクリーンにそれをリスタートするでしょう.
Now what happens if the new modules are broken? First of all, I see immediately an indication of the problems reported in the error_log file, which I tail -f immediately after a restart command. If there's a problem, I just put everything back as it was before:

これでもし新しいモジュールが壊れていたら何が起こりますか ? まず最初に, 私は restart コマンドの直後に tail -f をしているので, 私はすぐに error_log ファイルでリポートされた問題の兆候をみます. もし問題があれば, 私はすべてをこのようにして前のものに戻すだけです:

% mv rel bad && mv old rel && stop && sleep 3 && restart && err

Usually everything will be fine, and I have had only about 10 seconds of downtime, which is pretty good!

通常はすべてが正常になります, そして私がもつダウンタイムは 10 秒程度でしかありませんでした, それはかなりグッドです!


ライブスクリプトの意図的な無効化 : An Intentional Disabling of Live Scripts



What happens if you really must take down the server or disable the scripts? This situation might happen when you need to do some maintenance work on your database server. If you have to take your database down then any scripts that use it will fail.

もしあなたが本当にサーバをテイクダウンしたりスクリプトを無効にしなければならない場合は何が起こりますか ? このシチュエーションはあなたがあなたのデータベースサーバ上で何らかのメンテナンス作業を行う必要があるときに発生するかもしれません. あなたがあなたのデータベースをダウンさせなければならない場合はそれを使うスクリプトはすべてフェイル (# 失敗) するでしょう.
If you do nothing, the user will see either the grey An Error has happened message or perhaps a customized error message if you have added code to trap and customize the errors. See Redirecting Errors to the Client instead of to the error_logfor the latter case.

あなたが何もしないなら, ユーザはグレーの An Error has happened メッセージやあなたがトラップするための追加されたコードをもっていてエラーをカスタマイズしているならおそらくカスタマイズされたエラーメッセージのどちらかを見るでしょう. 後者のケースは Redirecting Errors to the Client instead of to the error_log (# error_log の代わりにクライアントにエラーをリダイレクトする) を参照してください.
A much friendlier approach is to confess to your users that you are doing some maintenance work and plead for patience, promising (keep the promise!) that the service will become fully functional in X minutes. There are a few ways to do this:

とても友好的なアプローチはあなたが何らかのメンテナンス作業をしていることをあなたのユーザに告白して辛抱をお願いし, そのサービスが X 分で完全に機能するようになることを約束する (約束は守って !) ことです. これを行うためにいくつかの方法があります:
The first doesn't require messing with the server. It works when you have to disable a script running under Apache::Registry and relies on the fact that it checks whether the file was modified before using the cached version. Obviously it won't work under other handlers because these serve the compiled version of the code and don't check to see if there was a change in the code on the disk.

1 つ目はサーバをいじくることを必要としません. あなたが Apache::Registry のもとで走っているスクリプトを無効化しなければならないときにそれは機能しそのファイルがキャッシュされたバージョンを使う前に修正されたかどうかをチェックするという事実に依存します. 他のハンドラはコンパイルされたコードのバージョンをサーブしディスク上のコードが変更されたかを確認しないので明らかにそれらの元では機能しません.
So if you want to disable an Apache::Registry script, prepare a little script like this:

ですからもしあなたが Apache::Registry スクリプトを無効化したい場合は, このような小さなスクリプトを準備してください:

/home/http/perl/maintenance.pl
#!/usr/bin/perl -Tw

use strict;
use CGI;
my $q = new CGI;
print $q->header, $q->p(
"Sorry, the service is temporarily down for maintenance.
It will be back in ten to fifteen minutes.
Please, bear with us.
Thank you!");

So if you now have to disable a script for example /home/http/perl/chat.pl, just do this:

そして今あなたが例えばスクリプト /home/http/perl/chat.pl を無効化しなければならない場合は, これを行うだけです:

% mv /home/http/perl/chat.pl /home/http/perl/chat.pl.orig
% ln -s /home/http/perl/maintenance.pl /home/http/perl/chat.pl

Of course you server configuration should allow symbolic links for this trick to work. Make sure you have the directive

もちろんこのトリックが機能するためにはあなたのサーバ構成がシンボリックリンクを許可していなければなりません. あなたがあなたの httpd.conf 内の <Location> または <Directory> 内にこのディレクティブ

Options FollowSymLinks

in the <Location> or <Directory> section of your httpd.conf.

をもっていることを確認してください.
When you're done, it's easy to restore the previous setup. Just do this:

あなたが完了したら, 以前のセットアップを簡単にリストアできます. これを行うだけです:

% mv /home/http/perl/chat.pl.orig /home/http/perl/chat.pl

wichi overwrites the symbolic link.

これはシンボリックリンクをオーバーライドします.
Now make sure that the script will have the current timestamp:

そしてそのスクリプトが現在のタイムスタンプをもっていることを確認します:

% touch /home/httpd/perl/chat.pl

Apache will automatically detect the change and will use the moved script instead.

Apache はその変更を自動的に検知してその移動されたスクリプトを代わりに使うようになります.
The second approach is to change the server configuration and configure a whole directory to be handled by a My::Maintenance handler (which you must write). For example if you write something like this:

2 番目のアプローチはサーバ構成を変更して My::Maintenance ハンドラ (これはあなたが書かねばなりません) によってディレクトリ全体が処理されるように構成します. 例えばあなたがこのようなものを書いた場合:

My/Maintenace.pm
----------------
use strict;
use Apache::Constants qw(:common);
sub handler {
my $r = shift;
print $r->send_http_header("text/plain");
print qq{
We apologize, but this service is temporarily stopped for
maintenance. It will be back in ten to fifteen minutes.
Please, bear with us. Thank you!
};
return OK;
}
1;

and put it in a directory that is in the server's @INC, to disable all the scripts in Location /perl you would replace:

それをそのサーバの @INC 内のディレクトリにおいて, Location /perl 内のすべてのスクリプトを無効化するためにあなたはリプレイスします:

<Location /perl>
SetHandler perl-script
PerlHandler My::Handler
[snip]
</Location>

with

をこれで

<Location /perl>
SetHandler perl-script
PerlHandler My::Maintenance
[snip]
</Location>

Now restart the server. Your users will be happy to go and read http://slashdot.org for ten minutes, knowing that you are working on a much better version of the service.

次にそのサーバをリスタートします. あなたのユーザはあなたがサービスのよりベターなバージョンに取り組んでいることを知ることで, ハッピーな気分で http://slashdot.org にいって 10 分間読むでしょう.
If you need to disable a location handled by some module, the second approach would work just as well.

あなたが何らかのモジュールにより処理されるロケーションを無効化する必要があるなら, 2 番目のアプローチがちょうどよく機能するでしょう.


SUID スタートアップスクリプト : SUID Start-up Scripts



If you want to allow a few people in your team to start and stop the server you will have to give them the root password, which is not a good thing to do. The less people know the password, the less problems are likely to be encountered. But there is an easy solution for this problem available on UNIX platforms. It's called a setuid executable.

あなたがあなたのチームの何人かの人にサーバのスタートとストップをできるようにしたいならあなたは彼らにその root パスワードを与えなければなりませんが, それはグッドな行為ではありません. パスワードを知る人が少ないほど, 問題に遭遇する可能性は少なくなります. しかし UNIX プラットフォームで利用可能なこの問題のための簡単なソリューションがあります. それは setuid executable (# setuid 実行可能ファイル) と呼ばれます.


SUID 実行ファイルの紹介 : Introduction to SUID Executables



The setuid executable has a setuid permissions bit set. This sets the process's effective user ID to that of the file upon execution. You perform this setting with the following command:

setuid executable は setuid パーミッションビットの設定をもっています. これはそのファイルの実行に際してプロセスの実効ユーザ ID をそれにセットします. あなたは次のコマンドでこのセッティングを実行します.

% chmod u+s filename

You probably have used setuid executables before without even knowing about it. For example when you change your password you execute the passwd utility, which among other things modifies the /etc/passwd file. In order to change this file you need root permissions, the passwd utility has the setuid bit set, therefore when you execute this utility, its effective ID is the same of the root user ID.

あなたはおそらく setuid executables について知ることなくそれを使ったことがあります. 例えばあなたが passwd ユーティリティを実行してあなたのパスワードを変更するとき, それはとりわけ /etc/passwd ファイルを変更します. このファイルを変更するためにあなたは root パーミッションが必要で, passwd ユーティリティは setuid ビットセットを持っています, したがってあなたがこのユーティリティを実行するとき, その実効 ID は root ユーザ ID と同じです.
You should avoid using setuid executables as a general practice. The less setuid executables you have the less likely that someone will find a way to break into your system, by exploiting some bug you didn't know about.

あなたは一般的なプラクティスとして setuid executables を使うことは避けなければなりません. あなたがもつ setuid executables が少ないほど誰かがあなたが知らないバグを利用して, あなたのシステムへの侵入方法をみつける可能性が少なくなります.
When the executable is setuid to root, you have to make sure that it doesn't have the group and world read and write permissions. If we take a look at the passwd utility we will see:

executable が root に setuid されているとき, あなたはそれが group と world (# あるいは other) の読込みと書込みパーミッションをもっていないことを確認しなければなりません. 私たちが passwd ユーティリティをみれば私たちはこれをみるでしょう:

% ls -l /usr/bin/passwd
-r-s--x--x 1 root root 12244 Feb 8 00:20 /usr/bin/passwd

You achieve this with the following command:

あなたは次のコマンドでこれを成すことができます:

% chmod 4511 filename

The first digit (4) stands for setuid bit, the second digit (5) is a compound of read (4) and executable (1) permissions for the user, and the third and the fourth digits are setting the executable permissions for the group and the world.

1 桁目の (4) は setuid ビットを表し, 2 桁目の (5) はユーザの読込み (4) と実行可能 (1) の複合で, 3 桁目と 4 桁目は group と world (# あるいは other) の実行可能パーミッションをセットします.


Apache スタートアップ SUID スクリプトのセキュリティ : Apache Startup SUID Script's Security



In our case, we want to allow setuid access only to a specific group of users, who all belong to the same group. For the sake of our example we will use the group named apache. It's important that users who aren't root or who don't belong to the apache group will not be able to execute this script. Therefore we perform the following commands:

このケースで, 私たちは特定のユーザグループにのみ setuid アクセスを許可したいと思います, その人たちはみな同じグループに属します. 私たちは私たちの例のために apache と名付けられたグループを使います. root でなかったり apache グループに属さないユーザはこのスクリプトを実行できないことは重要です. したがって私たちは次のコマンドを実行します:

% chgrp apache apachectl
% chmod 4510 apachectl

The execution order is important. If you swap the command execution order you will lose the setuid bit.

この実行順序は重要です. もしあなたがこのコマンドの実行順序を入れ換えるとあなたは setuid ビットを失います.
Now if we look at the file we see:

いま私たちがこのファイルを見ると私たちはこれを見ます:

% ls -l apachectl
-r-s--x--- 1 root apache 32 May 13 21:52 apachectl

Now we are all set... Almost...

これで私たちは準備万端です... ほとんど...
When you start Apache, Apache and Perl modules are being loaded, code can be executed. Since all this happens with root effective ID, any code executed as if the root user was doing that. You should be very careful because while you didn't gave anyone the root password, all the users in the apache group have an indirect root access. Which means that if Apache loads some module or executes some code that is writable by some of these users, users can plant code that will allow them to gain a shell access to root account and become a real root.

あなたの Apache をスタートすると, Apache と Perl モジュールがロードされ, コードが実行できるようになります. これはすべて root 実効 ID で起きるので, root ユーザがそれを行っているかのようにすべてのコードは実行されます. あなたが誰にも root パスワードを与えていなくても, apache グループのすべてのユーザは間接的な root アクセスをもっているのであなたはとても注意しなければなりません. つまり Apache がそれらのユーザの一部が書込める何らかのモジュールをロードしたり何かのコードを実行した場合, ユーザは root アカウントへのシェルアクセスをそれらに与えるコードを植え付けてリアルな root になることができます.
Of course if you don't trust your team you shouldn't use this solution in first place. You can try to check that all the files Apache loads aren't writable by anyone but root, but there are too many of them, especially in the mod_perl case, where many Perl modules are loaded at the server startup.

もちろんあなたがあなたのチームを信頼していないならあなたはそもそもこのソリューションを使うべきではありません. あなたは Apache がロードするすべてのファイルが root ではない誰かによって書込みができないことのチェックを試みることができますが, それらは多すぎます, 特に mod_perl のケースでは, サーバのスタート時に多くの Perl モジュールが読込まれます.
By the way, don't let all this setuid stuff to confuse you -- when the parent process is loaded, the children processes are spawned as non-root processes. This section has presented a way to allow non-root users to start the server as root user, the rest is exactly the same as if you were executing the script as root in first place.

ところで, この setuid というものに混乱しないようにしてください -- parent (# 親) プロセスがロードされたとき, その children (# 子) プロセスは非 root プロセスとして生み出されます. このセクションは非 root ユーザが root ユーザとしてサーバをスタートさせられるための方法を提示しましたが, 残り (# の処理) はあなたが最初から root としてスクリプトを実行した場合と全く同じです.


サンプル Apache スタートアップ SUID スクリプト : Sample Apache Startup SUID Script



Now if you are still with us, here is an example of the setuid Apache startup script.

さてまだあなたが私たちとともにあるならば, こちらが setuid Apache スタートアップスクリプトの例です.
Note the line marked WORKAROUND, which fixes an obscure error when starting mod_perl enabled Apache by setting the real UID to the effective UID. Without this workaround, a mismatch between the real and the effective UID causes Perl to croak on the -e switch.

WORKAROUND とマークされた行に注目してください, これは実効 UID にリアル UID を設定することによって mod_perl が有効化された Apache がスタートするときに曖昧なエラーをフィックスします. このワークアラウンド (# 回避策) がないと, リアルと実効 UID とのミスマッチに起因して -e スイッチで Perl が鳴きます (# croak).
Note that you must be using a version of Perl that recognizes and emulates the suid bits in order for this to work. This script will do different things depending on whether it is named start_httpd, stop_httpd or restart_httpd. You can use symbolic links for this purpose.

あなたはこれが機能するようにするために suid ビットを認識してエミュレートする Perl のバージョンを使わなければならないことに注意してください. このスクリプトはそれが start_httpd, stop_httpd または restart_httpd のどの名前が付けられているかによって違うことを行います. あなたはこの目的のためにシンボリックリンクを使えます.

suid_apache_ctl
---------------
#!/usr/bin/perl -T

# These constants will need to be adjusted.
# これらの定数は調整される必要あり
$PID_FILE = '/home/www/logs/httpd.pid';
$HTTPD = '/home/www/httpd -d /home/www';

# These prevent taint warnings while running suid
# これらは suid 実行中に汚染警告を防止する
$ENV{PATH} = '/bin:/usr/bin';
$ENV{IFS} = '';

# This sets the real to the effective ID, and prevents
# an obscure error when starting apache/mod_perl
# これは実効 ID にリアルをセットして, apache/mod_perl のスタート時に
# 曖昧なエラーを防止する
$< = $>; # WORKAROUND
$( = $) = 0; # set the group to root too (グループも root に)

# Do different things depending on our name
# 名前により違うことをする
($name) = $0 =~ m|([^/]+)$|;

if ($name eq 'start_httpd') {
system $HTTPD and die "Unable to start HTTP";
print "HTTP started.\n";
extit 0;
}

# extract the process id and confirm that it is numeric
# プロセス ID を抽出しそれが数字であることを確認
$pid = `cat $PID_FILE`;
$pid =~ /(\d+)/ or die "PID $pid not numeric";
$pid = $1;

if ($name eq 'stop_httpd') {
kill 'TERM',$pid or die "Unable to signal HTTP";
print "HTTP stopped.\n";
exit 0;
}

if ($name eq 'restart_httpd') {
kill 'HUP',$pid or die "Unable to signal HTTP";
print "HTTP restarted.\n";
exit 0;
}

die "Script must be named start_httpd, stop_httpd, or restart_httpd.\n";



マシンリブートの準備 : Preparing for Machine Reboot



When you run your own development box, it's okay to start the webserver by hand when you need to. On a production system it is possible that the machine the server is running on will have to be rebooted. When the reboot is completed, who is going to remember to start the server? It's easy to forget this task, and what happens if you aren't around when the machine is rebooted?

あなたがあなた独自の開発ボックスを実行するとき, あなたが必要な時に手動でウェブサーバをスタートして OK です. プロダクションシステム (# 本番環境) ではサーバが走っているマシンをリブートしなければならない可能性があります. そのリブートが完了したとき, 誰がサーバをスタートすることを覚えているでしょうか ? このタスクは簡単に忘れます, そしてもしあなたがそのマシンがリブートしたとき周囲にいなかった場合何が起きるでしょうか ?
After the server installation is complete, it's important not to forget that you need to put a script to perform the server startup and shutdown into the standard system location, for example /etc/rc.d under RedHat Linux, or /etc/init.d/apache under Debian Slink Linux.

サーバのインストールが完了した後, 標準のシステムロケーションにサーバのスタートアップとシャットダウンを実行するためのスクリプトをおくことをあなたが忘れないことは重要です, 例えば RedHat Linux では /etc/rc.d, また Slink Linux では /etc/init.d/apache です.
This is the directory which contains scripts to start and stop all the other daemons. The directory and file names vary from one Operating System (OS) to another, and even between different distributions of the same OS.

これはすべての他のデーモンをスタートとストップするためのスクリプトを含むディレクトリです. このディレクトリとファイル名はオペレーティングシステム (OS) によって, また同じ OS の違うディストリビューション間ででも異なります.
Generally the simplest solution is to copy the apachectl script to your startup directory or create a symbolic link from the startup directory to the apachectl script. You will find apachectl in the same directory as the httpd executable after Apache installation. If you have more than one Apache server you will need a separate script for each one, and of course you will have to rename them so that they can co-exist in the same directories.

一般的に最もシンプルなソリューションは apachectl スクリプトをあなたのスタートアップディレクトリにコピーするかスタートアップディレクトリから apachectl スクリプトへのシンボリックリンクを作成することです. あなたは Apache のインストールをした後に httpd 実行ファイル (# executable) と同じディレクトリで apachectl を見つけるでしょう. あなたが複数の Apache サーバを持っている場合あなたは個別にスクリプトを分ける必要があり, もちろんあなたはそれらが同じディレクトリで共存できるようにするためにそれらをリネームしなければなりません.
For example on a RedHat Linux machine with two servers, I have the following setup:

例えば 2 つのサーバをもつ RedHat Linux マシンで, 私は次のようなセットアップをもっています:

/etc/rc.d/init.d/httpd_docs
/etc/rc.d/init.d/httpd_perl
/etc/rc.d/rc3.d/S91httpd_docs -> ../init.d/httpd_docs
/etc/rc.d/rc3.d/S91httpd_perl -> ../init.d/httpd_perl
/etc/rc.d/rc6.d/K16httpd_docs -> ../init.d/httpd_docs
/etc/rc.d/rc6.d/K16httpd_perl -> ../init.d/httpd_perl

The scripts themselves reside in the /etc/rc.d/init.d directory. There are symbolic links to these scripts in other directories. The names are the same as the script names but they have numerical prefixes, which are used for executing the scripts in a particular order: the lower numbers are executed earlier.

スクリプトそれ自身は /etc/rc.d/init.d ディレクトリにあります. 他のディレクトリにはそれらへのシンボリックリンクがあります. その名前はそのスクリプト名とを同じですがそれらは数値のプレフィクスを持っています, これは特定の順序スクリプトを実行するために使われます: 小さい数が先に実効されます.
When the system starts (level 3) we want the Apache to be started when almost all of the services are running already, therefore I've used S91. For example if the mod_perl enabled Apache issues a connect_on_init() the SQL server should be started before Apache.

システムがスタートするとき (level 3) 私たちはサービスのほぼすべてがすでに走っている Apache をスタートさせたいと思います, ですから私たちは S91 を使います. 例えばもし mod_perl が有効化された Apache が connect_on_init() を発行する場合は SQL サーバは Apache の前にスタートされるべきです.
When the system shuts down (level 6), Apache should be stopped as one of the first processes, therefore I've used K16. Again if the server does some cleanup processing during the shutdown event and requires third party services to be running (e.g. SQL server) it should be stopped before these services.

システムがシャットダウンするとき (level 6), Apache は最初のプロセスの 1 つとしてストップされるべきです, ですから私たちは K16 を使います. 再びもしサーバがそのシャットダウンイベント中に何らかのクリーンアップ処理をしてサードパーティのサービスの実行 (e.g. SQL サーバ) を要求する場合それはそうしたサービスの前に停止されるべきです.
Notice that it's normal for more than one symbolic link to have the same sequence number.

複数のシンボリックリンクが同じシーケンス番号をもつのが普通であることに注目してください.
Under RedHat Linux and similar systems, when a machine is booted and its runlevel set to 3 (multiuser + network), Linux goes into /etc/rc.d/rc3.d/ and executes the scripts the symbolic links point to with the start argument. When it sees S91httpd_perl, it executes:

RedHat や同様のシステムのもとでは, マシンがブートされランレベルが 3 にセット (マルチユーザ + ネットワーク) されていると, Linux は /etc/rc.d/rc3.d/ にいってシンボリックリンクが start 引数で指し示す (# プレフィクスが S) スクリプトを実行します. それが S91httpd_perl をみると, それはこれを実行します:

/etc/rc.d/init.d/httpd_perl start

When the machine is shut down, the scripts are executed through links from the /etc/rc.d/rc6.d/ directory. This time the scripts are called with the stop argument, like this:

マシンがシャットダウンされると, /etc/rc.d/rc6.d ディレクトリからの (# プレフィクスが K の) リンクを通じてスクリプトが実行されます. このときスクリプトは stop 引数で呼ばれます, このように:

/etc/rc.d/init.d/httpd_perl stop

Most systems have GUI utilities to automate the creation of symbolic links. For example RedHat Linux includes the control-panel utility, which amongst other things includes the RunLevel Manager. (which can be invoked directly as either ntsysv(8) or tksysv(8)). This will help you to create the proper symbolic links. Of course before you use it, you should put apachectl or similar scripts into the init.d or equivalent directory. Or you can have a symbolic link to some other location instead.

ほとんどのシステムはシンボリックリンクの作成を自動化する GUI ユーティリティをもっています. 例えば RedHat Linux は control-panel ユーティリティを含んでいます, とりわけそれは RunLevel Manager を含みます. (これは ntsysv(8) または tksysv(8) として直接呼びだされることができます). これはあなたが適切なシンボリックリンクを作成することを助けます. もちろんあなたがそれを使う前に, あなたは apachectl や同様のスクリプトを init.d や同等のディレクトリに配置しなければなりません. あるいはあなたは代わりに他の場所へのシンボリックリンクを持つこともできます.
The simplest approach is to use the chkconfig(8) utility which adds and removes the services for you. The following example shows how to add an httpd_perl startup script to the system.

最もシンプルなアプローチはあなたのためにサービスを追加したり削除したりする chkconfig(8) ユーティリティを使うことです. 次の例はどのようにして httpd_perl スタートアップスクリプトをシステムに追加するを示します.
First move or copy the file into the directory /etc/rc.d/init.d:

最初にファイルを /etc/rc.d/init.d にファイルを移動またはコピーします:

% mv httpd_perl /etc/rc.d/init.d

Now open the script in your favorite editor and add the following lines after the main header of the script:

ここであなたのお気に入りのエディタでスクリプトをオープンしてそのスクリプトのメインヘッダの後に次の行を追加します:

# Comments to support chkconfig on RedHat Linux
# (RedHat Linux で chkconfig をサポートするためのコメント)
# chkconfig: 2345 91 16
# description: mod_perl enabled Apache Server
# (説明: mod_perl が有効化された Apache Server)

So now the beginning of the script looks like:

そしてそのスクリプトの始まりはこのようになります:

#!/bin/sh
#
# Apache control script designed to allow an easy command line
# interface to controlling Apache. Written by Marc Slemko,
# 1997/08/23
# (Apache のコントロールを簡単なコマンドラインインターフェイスで
# できるように設計された Apache コントロールスクリプト. Marc Slemko により書かれた,
# 1997/08/23)

# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 91 16
# description: mod_perl enabled Apache Server

#
# The exit codes retuned are:
# ...

Adjust the line:

行を調整します

# chkconfig: 2345 91 16

to your needs. The above setting says to says that the script should be started in levels 2, 3, 4, and 5, that its start priority should be 91, and that its stop priority should be 16.

あなたのニーズで. 上記セッティングはそのスクリプトがレベル 2, 3, 4 と 5 でスタートされるべきで, そのスタート優先度は 91 であり, そしてストップ優先度は 16 とするようにいっています.
Now all you have to do is to ask chkconfig to configure the startup scripts. Before we do that let's look at what we have:

これによってあなたがしなければならないことはそのスタートアップスクリプトを構成するために chkconfig に依頼をすることだけです. 私たちがそれを行う前に私たちが何をもっているのかを見てみましょう:

% find /etc/rc.d | grep httpd_perl

/etc/rc.d/init.d/httpd_perl

Which means that we only have the startup script itself. Now we execute:

これは私たちがスタートアップスクリプトそれ自体のみをもっていることを意味します. いま私たちはこれを実行して:

% chkconfig --add httpd_perl

and see waht has changed:

何が変わったかをみます:

% find /etc/rc.d | grep httpd_perl

/etc/rc.d/init.d/httpd_perl
/etc/rc.d/rc0.d/K16httpd_perl
/etc/rc.d/rc1.d/K16httpd_perl
/etc/rc.d/rc2.d/S91httpd_perl
/etc/rc.d/rc3.d/S91httpd_perl
/etc/rc.d/rc4.d/S91httpd_perl
/etc/rc.d/rc5.d/S91httpd_perl
/etc/rc.d/rc6.d/K16httpd_perl

As you can see chkconfig created all the symbolic links for us, using the startup and shutdown priorities as specified in the line:

あなたが見たとおり chkconfig はこの行で指定されたスタートアップとシャットダウンの優先度を使って, 私たちのためにすべてのシンボリックリンクを作成しました:

# chkconfig: 234 91 16

If for some reason you want to remove the service from the startup scripts, all you have to do is to tell chkconfig to remove the links:

もしあなたが何かの理由でスタートアップスクリプトからサービスを削除したいなら, あなたが行うべきことはそのリンクの削除を chkconfig に伝えることだけです:

% chkconfig --del httpd_perl

Now if we look at the files under the directory /etc/rc.d/ we see again only the script itself.

ここで私たちが /etc/rc.d/ ディレクトリの下のファイルを見ると私たちは再びそのスクリプトそれ自身だけを見ます.

% find /etc/rc.d | grep httpd_perl

/etc/rc.d/init.d/httpd_perl

Of course you may keep the startup script in any other directory as long as you can link to it. For example if you want to keep this file with all the Apache binaries in /usr/local/apache/bin, all you have to do is to provide a symbolic link to this file:

もちろんあなたがそれにリンクできる限りあなたはそのスタートアップスクリプトを他のディレクトリにキープすることもできます. 例えばあなたがこのファイルをすべての Apache バイナリと共に /usr/loca/apache/bin でキープしたいなら, あなたがやるべきなのはこのファイルへのシンボリックリンクの提供を行うことだけです:

% ln -s /usr/local/apache/bin/apachectl /etc/rc.d/init.d/httpd_perl

and then:

それから:

% chkconfig --add httpd_perl

Note that in case of using symlinks the link name in /etc/rc.d/init.d is what matters and not the name of the script the link points to.

シンボリックリンクを使うケースでは /etc/rc.d/init.d でのリンク名が大事であってリンクが指すスクリプトの名前ではないことに注意してください.


サーバを監視する. watchdog (# 番犬) : Monitoring the Server. A watchdog.



With mod_perl many things can happen to your server. It is possible that the server might die when you are not around. As with any other critical service you need to run some kind of watchdog.

mod_perl ではあなたのサーバに多くのことが起こりますえます. あなたがそばにいないときにサーバが die することもありえます. 他のクリティカルなサービスと同様にあなたは何らかの watchdog (# 監視プログラム) を実行する必要があります.
One simple solution is to use a slightly modified apachectl script, which I've named apache.watchdog. Call it from the crontab every 30 minutes -- or even every minute -- to make sure the server is up all the time.

シンプルなソリューションのひとつは少しだけ修正された apachectl スクリプトを使うことで, それを私は apache.watchdog と名付けました. サーバが常にアップしているかを確認するために crontab から 30 分ごと -- または毎分ごと -- にそれをコールしします.
The crontab entry for 30 minutes intervals:

その 30 分間隔のための crontab のエントリです:

0,30 * * * * /path/to/the/apache.watchdog >/dev/null 2>&1

The script:

そのスクリプト:

#!/bin/sh

# this script is a watchdog to see wheter the server is online
# It tries to restart the server, and if it's
# down it sends an email alert to admin
# このスクリプトはサーバがオンラインかどうかを見るための watchdog
# サーバのリスタートを試みて, それがダウンしているなら
# admin に email アラートを送信する

# admin's email
EMAIL=webmaster@example.com

# the path to your PID file
PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid

# the path to your httpd binary, including options if necessary
HTTPD=/usr/local/sbin/httpd_perl/httpd_perl

# check for pidfile
if [ -f $PIDFILE ] ; then
PID=`cat $PIDFILE`

if kill -0 $PID; then
STATUS="httpd (pid $PID) running"
RUNNING=1
else
STATUS="httpd (pid $PID?) not running"
RUNNING=0
fi
else
STATUS="httpd (no pid file) not running"
RUNNING=0
fi

if [ $RUNNING -eq 0 ]; then
echo "$0 $ARG: httpd not running, trying to start"
if $HTTPD ; then
echo "$0 $ARG: http started"
mail $EMAIL -s "$0 $ARG: httpd started" > /dev/null 2>&1
else
echo "$0 $ARG: httpd could not be started"
mail $EMAIL -s \
"$0 $ARG: httpd could not be started" > /dev/null 2>&1
fi
fi

Another approach, probably even more practical, is to use the cool LWP Perl package to test the server by trying to fetch some document (script) served by the server. Why is it more practical? Because while the server can be up as a process, it can be stuck and not working. Failing to get the document will trigger restart, and "probably" the problem will go away.

他のアプローチ, おそらくよりいっそう実践的な, はそのサーバによりサーブされている何らかのドキュメント (スクリプト) を取得することをトライすることでサーバをテストするためにクールな LWP Perl パッケージを使うことです. それがより実践的なのはなぜでしょうか ? そのサーバがプロセスとしてアップできていても, それがスタックして機能しないことがあるからです. ドキュメントのゲットに失敗するとリスタートがトリガーされて, "おそらく" その問題はなくなるでしょう.
Like before we set a cronjob to call this script every few minutes to fetch some very light script. The best thing of course is to call it every minute. Why so often? If your server starts to spin and trash your disk space with multiple error messages filling the error_log, in five minutes you might run out of free disk space which might bring your system to its knees. Chances are that no other child will be able to serve requests, since the system will be too busy writing to the error_log file. Think big--if you are running a heavy service (which is very fast since you are running under mod_perl) adding one more request every minute will not be felt by the server at all.

前と同様に私たちはあるとても軽量なスクリプトをフェッチするために数分ごとにこのスクリプトをコールするように cronjob をセットしました. なぜそれほど頻繁に ? もしあなたのサーバがスピンし始めて複数のエラーメッセージが error_log を満たしてあなたのディスクスペースがめちゃくちゃにななると, 5 分以内であなたはフリーのディスクスペースを使い切ってあなたのシステムを屈服させるかもしれません. 他の child はリクエストをサーブすることができないでしょう, そのシステムは error_log ファイルへの書込みでとてもビジーになるからです. 大きく考えてください - あなたがヘビーなサービス (それはあなたが mod_perl のもとで実行しているのでとても高速です) を実行しているなら毎分のリクエストを 1 つ余分に追加してもサーバは何も感じないでしょう.
So we end up with a crontab entry like this:

ですから私たちは crontab エントリをこのようにします:

* * * * * /path/to/the/watchdog.pl >/dev/null 2>&1

And the watchdog itself:

そして watchdog それ自体がこれです:

#!/usr/bin/perl -wT

# untaint
# 非汚染
$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

use strict;
use diagnostics;
use URI::URL;
use LWP::MediaTypes

my $VERSION = '0.01';
use vars qw($ua $proxy);
$proxy = '';

require LWP::UserAgent;
use HTTP::Status;

###### Config #########
my $test_script_url = 'http://www.example.com:81/perl/test.pl';
my $monitor_email = 'root@localhost';
my $restart_command = '/usr/local/sbin/httpd_perl/apachectl restart';
my $mail_program = '/usr/lib/sendmail -t -n';
######################

$ua = new LWP::UserAgent;
$ua->agent("$0/watchdog " . $ua->agent);
# Uncomment the proxy if you access a machine from behind a firewall
# あなたがファイアウォールの背後からマシンにアクセスする場合はこのプロクシをアンコメント
# $proxy = "http://www-proxy.com";
$ua->proxy('http', $proxy) if $proxy;

# If it returns '1' it means we are alive
# '1' をリターンした場合は私たちが生存していることを意味する
exit 1 if checkurl($test_script_url);

# Houston, we have a problem.
# The server seems to be down, try to restart it.
# ヒューストン, 問題が発生した.
# サーバがダウンしているようだ, リスタートを試みる.
my $status = system $restart_command;

my $message = ($status == 0)
? "Server was down and successfully restarted!"
: "Server is donw. Can't restart.";

my $subject = ($status == 0)
? "Attention! Webserver restarted"
: "Attention! Webserver is down. can't restart";

# email the monitoring person
# モニタリング担当者に email
my $to = $monitor_email;
my $from = $monitor_email;
send_mail($from,$to,$subject,$message);

# input: URL to check
# output: 1 for success, 0 for failure
#######################
sub checkurl{
my ($url) = @_;

# Fetch document
# ドキュメントの取得
my $res = $ua->request(HTTP::Request->new(GET => $url));

# Check the result status
# 結果ステータスのチェック
return 1 if is_success($res->code);

# failed
# 失敗した
return 0;
} # end of sub checkurl
# サブルーチン checkurl の終わり

# send email about the problem
# 問題についての email を送信
#######################
sub send_mail{
my ($from,$to,$subject,$messagebody) = @_;

open MAIL, "|$mail_program"
or die "Can't open a pipe to a $mail_program :$!\n";

print MAIL <<__END_OF_MAIL__;
To: $to
From: $from
Subject: $subject

$messagebody

__END_OF_MAIL__

close MAIL;
}



シングルプロセスモードでサーバを実行する : Running a Server in Single Process Mode



Often while developing new code, you will want to run the server in single process mode. See Sometimes it works Sometimes it does Not and Names collisions with Modules and libs. Running in single process mode inhibits the server from "daemonizing", and this allows you to run it under the control of a debugger more easily.

しばしば新しいコードの開発で, あなたはサーバをシングルプロセスモードで実行したいことがあります. Sometimes it works Sometimes it does Not (ときどき機能してときどき機能しない) と Names collisions with Modules and libs (モジュールとライブラリでの名前衝突) を参照してください. シングルプロセスモードでの実行はサーバの "デーモン化" を抑制し, これがあなたがデバッガのコントロールのもとで実行することをより簡単にしてくれます.

% /usr/local/sbin/httpd_perl/httpd_perl -X

When you use the -X switch the server will run in the foreground of the shell, so you can kill it with Ctrl-C.

あなたが -X スイッチを使うとそのサーバはシェルのフォアグラウンドで実行されます, ですからあなたはそれを Ctrl-C でキルできます.
Note that in -X (single-process) mode the server will run very slowly when fetching images.

-X (シングルプロセス) モードでイメージを取得するときサーバはとても遅く走ることに注意してください.
Note for Netscape users:

Netscape ユーザへの注意:
If you use Netscape while your server is running in single-process mode, HTTP's KeepAlive feature gets in the way. Netscape tries to open multiple connections and keep them open. Because there is only one server process listening, each connection has to time out before the next succeeds. Turn off KeepAlive in httpd.conf to avoid this effect while developing. If you use the image size parameters, Netscape will be able to render the page without the images so you can press the browser's STOP button after a few seconds.

あなたが Netscape を使っていてあなたのサーバがシングルプロセスモードで走っている場合, HTTP の KeepAlive 機能が邪魔になります. Netscape は複数のコネクションをオープンしそれらをオープンしたままにすることをトライします. リスニングしているサーバプロセスはひとつだけなので, 次が成功する前に各コネクションはタイムアウトしなければなりません. 開発中はこの影響を避けるために httpd.conf で KeepAlive をオフにしてください. もしあなたがイメージサイズパラメータを使っているなら, Netscape はそのイメージ無しでページをレンダリングできますのであなたは数秒後にブラウザの STOP ボタンを押せます.
In addition you should know that when running with -X you will not see the control messages that the parent server normally writes to the error_log ("server started", "server stopped" etc). Since httpd -X causes the server to handle all requests itself, without forking any children, there is no controlling parent to write the status messages.

加えて -X で実行したときあなたは parent サーバが error_log に普通は書込むコントロールメッセージ ("server started", "server stopped" etc) を見れないことをあなたは知っておくべきです. httpd -X に起因してサーバは children をフォークすることなく, すべてのリクエストをそれ自身で処理するので, ステータスメッセージを書込むためのコントロールをする parent はいません.


開発者ごとにパーソナルサーバをスタートする : Starting a Personal Server for Each Developer



If you are the only developer working on the specific server:port you have no problems, since you have complete control over the server. However, often you will have a group of developers who need to develop mod_perl scripts and modules concurrently. This means that each developer will want to have control over the server - to kill it, to run it in single server mode, to restart it, etc., as well as having control over the location of the log files, configuration settings like MaxClients, and so on.

あなたが特定の server:port で作業する唯一の開発者ならあなたはなんの問題ももちません, あなたはそのサーバの完全なコントロールをもっているからです. しかし, しばしばあなたは mod_perl スクリプトとモジュールを同時に開発する必要がある開発者のグループをもちます. これは各開発者がサーバを kill する, シングルサーバモードで実行する, リスタートする, etc., それからログファイルの場所のコントロール, MaxClients のような構成セッティングをする, など - そのコントロールをしたがることを意味します.
You can work around this problem by preparing a few httpd.conf files and forcing each developer to use

あなたはいくつかの httpd.conf ファイルを準備して開発者にこれを使うことを強制することでこの問題を回避できます

httpd_perl -f /path/to/httpd.conf

but I approach it in a different way. I use the -Dparameter startup option of the server. I call my version of the server

しかし私は異なる方法でこれにアプローチします. 私はそのサーバの -Dparameter スタートアップオプションを使います. わたしは私のサーバのバージョンでこれをコールします

% http_perl -Dstas
# stas はユーザ名

In httpd.conf I write:

httpd.conf で私はこれを書きます:

# Personal devalopment Server for stas
# stas uses the server running on port 8000
# ---
# stas のための個人用開発サーバ
# stas は port 8000 で走るサーバを使う
<IfDefine stas>
Port 8000
PidFile /usr/local/var/httpd_perl/run/httpd.pid.stas
ErrorLog /usr/local/var/httpd_perl/logs/error_log.stas
Timeout 300
KeepAlive On
MinSapreServer 2
MaxSpareServer 2
StartServers 1
MaxClients 3
MaxRequestsPerChild 15
</IfDefine>

# Personal develop Server for userfoo
# userfoo uses server running on port 8001
# ---
# userfoo のための個人用開発サーバ
# userfoo は port 8001 で走るサーバを使う
<IfDefine userfoo>
Port 8001
PidFile /usr/local/var/httpd_perl/run/httpd.pid.userfoo
ErrorLog /usr/local/var/httpd_perl/logs/error_log.userfoo
Timeout 300
KeepAlive Off
MinSapreServer 1
MaxSpareServer 2
StartServers 1
MaxClients 5
MaxRequestsPerChild 0
</IfDefine>

With this technique we have achieved full control over start/stop, number of children, a separate error log file, and port selection for each server. This saves Stas from getting called every few minutes by Eric: "Stas, I'm going to restart the server".

このテクニックで私たちは start/stop, childiren の数, 分割されたエラーログファイル, それと各サーバの port 選択のフルコントロールを達成できます. これは Stas が Eric によって数分ごとに呼びだされることから守ります: "Stas, 僕はサーバをリスタートするよ".
In the above technique, you need to discover the PID of your parent httpd_perl process, which is written in /usr/local/var/httpd_perl/run/httpd.pid.stas (and the same for the user eric). To make things even easier we change the apachectl script to do the work for us. We make a copy for each developer called apachectl.username and we change two lines in each script:

上記テクニックで, あなたはあなたの parent の httpd_perl プロセスの PID を見つける必要があり, それは /usr/local/var/httpd_perl.pid.stas に書かれます (user eric もまた同じです). さらに簡単なものにするために私たちは apachectl スクリプトを変更して私たちのための作業を行います. 私たち各開発者のために apachectl.username と呼ばれるコピーを作成して各スクリプトで 2 つの行を変更します:

PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid.username
HTTPD='/usr/local/sbin/httpd_perl/httpd_perl -Dusername'

So for the user stas we prepare a startup script called apachectl.stas and we change these two lines in the standard apachectl script as it comes unmodified from Apache distribution.

ですからユーザ stas のために私たちは apachectl.stas と呼ばれるスタートアップスクリプトを準備して Apache ディストリビューションから変更されていない標準の apachectl スクリプトのこれら 2 行を変更します.

PIDFILE=/usr/local/var/httpd_perl/run/httpd.pid.stas
HTTPD='/usr/local/sbin/httpd_perl/httpd_perl -Dstas'

So now when user stas wants to stop the server he will execute:

そしてユーザ stas がサーバをストップしたいときに彼はこれを実行します:

apachectl.stas stop

And to start

それとスタートするには:

apachectl.stas start

Certainly the rest of the apachectl arguments apply as before.

もちろん他の apachectl 引数は以前と同様に適用されます.
You might think about having only one apachectl and know who is calling by checking the UID, but since you have to be root to start the server it is not possible, unless you make the setuid bit on this script, as we've explained in the beginning of this chapter. If you do so, you can have a single apachectl script for all developers, after you modify it to automatically find out the UID of the user, who executes the script and set the right paths.

あなたは apachectl をひとつだけもち UID をチェックすることによってコールしている人を知ろうとするかもしれませんが, あなたはサーバをスタートするために root である必要があるので, このチャプタの冒頭で私たちが説明したように, あなたがこのスクリプトで setuid ビットを作成しない限り, それはできません. もしあなたがそれをする場合, あなたがスクリプトを実行したユーザの UID を自動的に見つけだして, 正しいパスを設定するようにそれを修正したあと, あなたはすべての開発者のためにひとつの apachectl スクリプトをもつことができます.
The last thing is to provide developers with an option to run in single process mode by:

最後のものはシングルプロセスモードでの実行をオプションで開発者に提供します:

/usr/local/sbin/httpd_perl/httpd_perl -Dstas -X

In addition to making life easier, we decided to use relative links everywhere in the static documents, including the calls to CGIs. You may ask how using relative links will get to the right server port. It's very simple, we use mod_rewrite.

生活を簡単にすることに加えて, 私たちは CGI へのコールも含めて, 静的ドキュメントのあらゆる場所で, 相対リンクを使うことを決定しました. あなたは使っている相対リンクがどのようにして正しいサーバ port をゲットするかを尋ねることができます. それはとてもシンプルで, 私たちは mod_rewrite を使います.
To use mod_rewrite you have to configure your httpd_docs server with --enable-module=rewrite and recompile, or use DSO and load the module in httpd.conf. In the httpd.conf of our httpd_docs server we have the following code:

mod_rewrite を使うためにあなたは --enable-module=rewrite であなたの httpd_docs サーバを構成し再コンパイルするか, DSO を使い httpd.conf でモジュールをロードしなければなりません. 私たちの httpd_docs サーバの httpd.conf で私たちは次のコードをもっています:

RewriteEngine on

# stas's server
# port = 8000
RewiteCond %{REQUEST_URI} ^/(perl|cgi-perl)
RewiteCond %{REMOTE_ADDR} 123.34.45.56
RewiteRule ^(.*) http://example.com:8000/$1 [P,L]

# eric's server
# port = 8001
RewiteCond %{REQUEST_URI} ^/(perl|cgi-perl)
RewiteCond %{REMOTE_ADDR} 123.34.45.57
RewiteRule ^(.*) http://example.com:8001/$1 [P,L]

# all the rest
RewiteCond %{REQUEST_URI} ^/(perl|cgi-perl)
RewiteRule ^(.*) http://example.com:81/$1 [P,L]

The IP addresses are the addresses of the developer desktop machines (where they are running their web browsers). So if an html file includes a relative URI /perl/test.pl or even http://www.example.com/perl/test.pl, clicking on the link will be internally proxied to http://www.example.com:8000/perl/test.pl if the click has been made at the user stas's desktop machine, or to http://www.example.com:8001/perl/test.pl for a request generated from the user eric's machine, per our above URI rewrite example.

この IP アドレスは開発者のデスクトップマシン (彼らの web ブラウザが走っているところ) のアドレスです. ですからもし html ファイルが相対 URI /perl/test.pl あるいは http://www.example.com/perl/test.pl を含む場合, 私たちの上記 URI リライト例では, そのリンクでクリックするとクリックがユーザ stas のデスクトップマシンでされたなら http://www.example.com:8000/perl/test.pl に, ユーザ eric のマシンから生成されたリクエストには http://www.example.com:8001/perl/test.pl に内部的にプロクシされます.
Another possibility is to use REMOTE_USER variable if all the developers are forced to authenticate themselves before they can access the server. If you do, you will have to change the RewriteRules to match REMOTE_USER in the above example.

もうひとつの可能性はすべての開発者がサーバにアクセスする前に彼ら自身の認証を強制されている場合に REMOTE_USER 変数を使うことです. もしあなたがそれをするなら, あなたは上記例で REMOTE_USER にマッチするように RewriteRules を変更する必要があります.
We wish to stress again, that the above setup will work only with relative URIs in the HTML code. If you choose to generate full URIs including non-80 port the requests originated from this HTML code will bypass the light server listening to the default port 80, and go directly to the server:port of the full URI.

私たちは上記ステップが HTML コードの相対 URI でのみ機能することを, 再度強調したいと思います. あなたが非 80 ポートを含むフル URI を選択した場合この HTML コードに基づくリクエストはデフォルト port 80 をリッスンする light サーバをバイパスし, フル URI の server:port に直接行きます.


サーバの Perl 環境をエミュレートするためのラッパ : Wrapper to Emulate the Server Perl Environment



Often you will start off debugging your script by running it from your favorite shell program. Sometimes you encounter a very weird situation when the script runs from the shell but dies when processed as a CGI script by a web-server. The real problem often lies in the difference between the environment variables that is used by your web-server and the ones used by your shell program.

しばしばあなたはあなたのお気に入りのシェルプログラムからあなたのスクリプトを実行してそのスクリプトのデバッグを始めます. ときおりあなたはそのシェルからスクリプトを実行したが web サーバにより CGI として処理されたときに die するというとても奇妙な状況に遭遇します. リアルな問題は大抵あなたの web サーバによって使われる環境変数とあなたのシェルプログラムによって使われるそれとの違いにあります.
For example you may have a set of non-standard Perl directories, used for local Perl modules. You have to tell the Perl interpreter where these directories are. If you don't want to modify @INC in all scripts and modules, you can use a PERL5LIB environment variable, to tell Perl where the directories are. But then you might forget to alter the mod_perl startup script to correct @INC there as well. And if you forget this, you can be quite puzzled why the scripts are running from the shell program, but not from the web.

例えばあなたはローカルの Perl モジュールに使われる, 非標準の Perl ディレクトリのセットをもっているかもしれません. あなたはそれらのディレクトリがどこにあるかを Perl インタプリタに伝えなければなりません. あなたがすべてのスクリプトとモジュールで @INC を修正したくない場合, あなたはそのディレクトリがどこにあるかを Perl に伝えるために, PERL5LIB 環境変数を使うことができます. しかしあなたは mod_perl スタートアップスクリプトを変更してそこの @INC も修正することを忘れるかもしれません. そしてもしあなたがこれを忘れると, あなたはなぜスクリプトがシェルプログラムからは走るのに, web ではそうでないことにとても困惑することになります.
Of course the error_log will help as well to find out what the problem is, but there can be other obscure cases, where you do something different at the shell program and your scripts refuse to run under the web-server.

もちろん error_log は何が問題かを見つけだす助けをしますが, あなたがシェルプログラムで何か違うことを行うとあなたスクリプトが web サーバのもとでの実行を拒むというようなまた別のあいまいなケースになることもあります.
Another example is when you have more than one version of Perl installed. You might call the first version of the Perl executable in the first script's line (the shebang line), but to have the web-server compiled with another Perl version. Since mod_perl ignores the path to the Perl executable at the first line of the script, you can get quite confused the code won't do same when processed as request, compared to be executed from the command line. it will take a while before you realize that you test the scripts from the shell program using the wrong Perl version.

もうひとつの例はあなたが複数のインストールされた Perl バージョンをもっているときです. あなたは最初のスクリプト行 (シェバン行) で Perl 実行ファイルの最初のバージョンをコールするかもしれませんが, web サーバは別の Perl バージョンでのコンパイルをもちます. mod_perl がそのスクリプトの最初の行の Perl 実行ファイルへのパスを無視するからで, あなたはコマンドラインからの実行と比較して, リクエストととして処理するときにコードが同じことを行わずとても混乱するかもしれません. あなたが誤った Perl バージョンを使ってシェルプログラムからそのスクリプトをテストしていることにあなたが気づくまでしばらくかかるでしょう.
The best debugging approach is to write a wrapper that emulates the exact environment of the server, first deleting environment variables like PERL5LIB and then calling the same perl binary that it is being used by the server. Next, set the environment identical to the server's by copying the Perl run directives from the server startup and configuration files or even require()'ing the startup file, if it doesn't include Apache:: modules stuff, unavailable under shell. This will also allow you to remove completely the first line of the script, since mod_perl doesn't need it anyway and the wrapper knows how to call the script.

ベストなデバッグのアプローチはサーバの正確な環境をエミュレートするラッパーを書くことで, 最初に PERL5LIB のような環境変数を削除してそれからサーバによって使われているのと同じ perl バイナリをコールします. 次に, サーバスタートアップと構成ファイルから Perl 実行ディレクティブをコピーするかあるいはシェルのもとでは利用できない, Apache::modules のものが含まれていない場合は, スタートアップファイルを require() することでサーバと同一の環境をセットします. これはまたあなたがスクリプトの最初の行を完全に削除することもできるようにします, どっちみち mod_perl はそれを必要とせずラッパーがそのスクリプトの呼びだし方を知っているからです.
Here is an example of such a script. Note that we force the use of -Tw when we call the real script. Since when debugging we want to make sure that the code is working when the taint mode is on, and we want to see all the warnings, to help Perl help us have a better code.

こちらがそのようなスクリプトの例です. 私たちが実際のスクリプトをコールするときに私たちは -Tw の使用を強制することに注意してください. デバッグするときにそのコードが汚染 (# taint) モードがオンで機能するかを私たちは確認したいからであり, 私たちがベターなコードをもつことを Perl help が助けてくれるようにするために私たちはすべての警告をみたいからです.
We have also added the ability to pass parameters, which will not happen when you will issue a request to script, but it can be helpful at times.

私たちはパラメータを渡すための機能も追加しました, それはあなたがスクリプトにリクエストを発行しても発生しませんが, 場合によっては役立ちます.

#!/usr/bin/perl -w

# This is a wrapper example
# ---
# これはラッパーの例

# It simulates the web server environment by setting @INC and ohter
# stuff, so what will run under this wrapper will run under Web and
# vice versa.
# ---
# @INC とその他をセッティングすることで web サーバ環境をシミュレート
# しますので, このラッパーのもとで走る者は Web のもとで走り
# 逆 (# shell プログラムのもとで) もまたしかりです.

#
# Usege: wrap.pl some_cgi.pl
#
BEGIN {
# we want to make a complete emulation, so we must reset all the
# paths and add the standard Perl libs
#---
# 私たちは完全なエミュレーションをしたいので, 私たちは
# すべてのパスをリセットして標準の Perl libs を追加しなければなりません
@INC =
qw(/usr/lib/perl5/5.00503/i386-linux
/usr/lib/perl5/5.00503
/usr/lib/perl5/site_perl/5.005/i386-linux
/usr/lib/perl5/site_perl/5.005
.
);
}

use strict;
use File::Basename;

# process the passed params
# 渡されたパラメータの処理
my $cgi = shift || '';
my $params = (@ARGV) ? join(" ", @ARGV) : '';

die "Usage:\n\t$0 some_cgi.pl\n" unless $cgi;

# Set the environment
# 環境のセット
my $PERL5LIB = join ":", @INC;

# if the path includes the directory
# we extract it and chdir there
#---
# パスがディレクトリを含んでいる場合
# それを抽出してそこに chdir する
if (index($cgi, '/') >= 0) {
my $dirname = dirname($cgi);
chdir $dirname of die "Can't chdir to $dirname: $! \n";
$cgi =~ m|$dirname/(.*)|;
$cgi = $1;
}

# run the cgi from the script's directory
# Note that we set Warning and Taint modes ON!!!
#---
# スクリプトのディレクトリから cgi を実行する
# 警告と汚染 (# Taint) モードを ON にセットすることに注目!!!
system qq{/usr/bin/perl -I$PERL5LIB -Tw $cgi $params};



サーバメンテナンス雑用 : Server Maintenance Chores



It's not enough to have your server and service up and running. You have to maintain the server even when everything seems to be fine. This includes security auditing, keeping an eye on the size of remaining unused disk space, available RAM, the load of the system, etc.

あなたのサーバとサービスを立ち上げて走らせるだけでは不十分です. あなたはすべてがうまくいっているようにみえてもサーバを保守しなければなりません. これはセキュリティの監査, 残りの未使用のディスクスペース, 利用可能な RAM, システムの負荷, etc に目を光らせることを含みます.
If you forget about these chores one day (sooner or later) your system will crash either because it has run out of free disk space, all the available CPU has been used and system has started heavily to swap or someone has broken in. Unfortunately the scope of this guide is not covering the latter, since it will take more than one book to profoundly cover this issue, but the rest of the thing are quite easy to prevent if you follow our advices.

ある日 (遅かれ早かれ) あなたがこれらの雑用を忘れたとするとあなたのシステムはフリーのディスクスペースが不足した, 利用可能なすべての CPU が使われてシステムが頻繁なスワップをしはじめたまたは誰かが侵入したかのいずれかでクラッシュするでしょう. 残念ながらこのガイドのスコープは後者をカバーしていません, この課題を深くカバーするには複数の本がいるからですが, もしあなたが私たちのアドバイスに従うなら残りのものはとても簡単に防ぐことができます.
確かに, あなたの特定のシステムがもつべき保守の雑用はここではカバーされていないかもしれません, しかし少なくともこれらの雑用がリアルで気をつけなければならないことをあなたは気づかされるでしょう.


ログファイルの処理 : Handling Log Files



There are two issues to solve with log files. First they should be rotated and compressed on the constant basis, since they tend to use big parts of the disk space over time. Second these should be monitored for possible sudden explosive growth rates, when something goes astray in your code running at the mod_perl server and the process starts to log thousands of error messages in second without stopping, until all the disk space is used, and the server cannot work anymore.

ログファイルで解決する 2 つの課題があります. 最初にそれを常にローテートさせ圧縮しなければなりません, それは時間とともにディスクスペースの大部分を使う傾向があるからです. 次に mod_perl サーバで走っているあなたのコードで何かが道を踏み外し, 全てのディスクスペースが使われて, そのサーバが機能しなくなるまで, そのプロセスがストップすることなく秒間数千のエラーメッセージを記録し始めたときに, それらが突然爆発的に増加する可能性のためにモニタされなければなりません.


ログローテーション : Log Rotation



The first issue is solved by having a process run by crontab at certain times (usually off hours, if this term is still valid in the Internet era) and rotate the logs. The log rotation includes the current log file renaming, server restart (which creates a fresh new log file), and renamed file compression and/or moving it on a different disk.

最初の課題は特定の時間 (通常は時間外, この用語がインターネット時代でもまだ有効なら) で crontab によるプロセスの実行を持つことによって解決されます. そのログローテーションは現在のログファイルのリネーム, サーバのリスタート (これはフレッシュな新しいログファイルを作成する), それからリネームされたファイルの圧縮 and/or 別のディスクへの移動を含みます.
For example if we want to rotate the access_log file we could do:

例えばもしあなたが access_log をローテートしたいなら私たちはこのようにします:

% mv access_log access_log.renamed
% apachectl restart
% sleep 5; # allow all children to complete requests and logging
# now it's safe to use access_log.renamed
#---
# すべての children がリクエストとロギングを完了できるようにする
# これで access_log.renamed を安全につかえる
% mv access_log.renamed /some/directory/on/another/disk

This is the script that we run from the crontab to rotate the log files:

これは私たちがログファイルをローテートするために crontab から実行するスクリプトです:

#!/usr/local/bin/perl -Tw

# This script does log rotation. Called from crontab
# このスクリプトはログローテーションをする. crontab からコールされる

use strict;
$ENV{PATH}='/bin:/usr/bin';

### configuration
### 構成
my @logfiles = qw(access_log error_log);
umask 0;
my $server = "httpd_perl";
my $logs_dir = "/usr/local/var/$server/logs";
my $restart_command = "/usr/local/sbin/$server/apachectl restart";
my $gzip_exec = "/usr/bin/gzip";

my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
my $time = sprintf "%0.4d.%0.2d.%0.2d-%0.2d.%0.2d.%0.2d",
$year+1900,++$mon,$mday,$hour,$min,$sec;
$^I = ".$time";

# rename log files
# ログファイルのリネーム
chdir $log_dir;
@ARGV = @logfiles;
while (<>) {
close ARGV;
}

# now restart the server so the logs will be restarted
# ここでサーバをリスタートするのでログはリスタートする
system $restart_command;

# allow all children to complete request and logging
# 全ての children がリクエストとロギングを完了できるようにする
sleep 5;

# compress log files
# ログファイルの圧縮
foreach (@logfiles) {
system "$gzip_exec $_.$time";
}

Note: Setting $^I sets the in-place edit flag to a dot followed by the time. We copy the names of the logfiles into @ARGV, and open each in turn and immediately close them without doing any changes; but because the in-place edit flag is set they are effectively renamed.

Note: $^I の設定はドットに time が続くように in-place エディットフラグをセットします. 私たちはログファイルの名前を @ARGV にコピーして, それらを順番にオープンして何も変更することなくすぐにクローズします; しかし in-place エディットフラグがセットされているのでそれらは効率よくリネームされます.
As you see the rotated files will include the date and the time in their filenames.

あなたが見たようにローテションされたファイルはそのファイル名に日付と時間を含みます.
Here is a more generic set of scripts for log rotation. Cron job fires off setuid script called log-roller that looks like this:

こちらはログローテーション用スクリプトのよりジェネリックなセットです. Cron ジョブはこのような log-roller と呼ばれる setuid スクリプトを起動します:

#!/usr/bin/perl -Tw
use strict;
use File::Basename;

$ENV{PATH} = "/usr/ucb:/bin/:/usr/bin";

my $ROOT = "/WWW/apche"; # names are relative to this (これに関連する名前)
my $CONF = "$ROOT/conf/httpd.conf"; # master conf (マスターコンフィグファイル)
my $MIDNIGHT = "MIDNIGHT"; # name of program in each logdir (各ログディレクトリ内のプログラム名)

my ($user_id, $group_id, $pidfile); # will be set during parse of conf (コンフィグファイルの解析中にセットされる)
die "not running as root if $>; # (# $> : 実効 uid)

chdir $ROOT or die "Cannot chdir $ROOT: $!";

my %midnights;
open CONF, "<$CONF" or die "Cannot open $CONF: $!";
while (<CONF>) {
if (/^User (\w+)/i) {
$user_id = getpwnam($1);
next;
}
if (/^Group (\w+)/i) {
$group_id = getgrnam($1);
next;
}
if (/^PidFile (.*)/i) {
$pidfile = $1;
next;
}
next unless /^ErrorLog (.*)/i;
my $midnight = (dirname $1)."/$MIDNIGHT";
next unless -x $midnight;
$midnights{$midnight}++;
}
close CONF;

die "missing User definition" unless defined $user_id;
die "missing Group definition" unless defined $group_id;
die "missing PidFile definition" unless defined $pidfile;

open PID, $pidfile or die "Cannot open $pidfile: $!";
<PID> =~ /(\d+)/;
my $httpd_pid = $1;
close PID;
die "missing pid definition" unless defined $httpd_pid and $httpd_pid;
kill 0, $httpd_pid or die "cannot find pid $httpd_pid: $!";

for (sort keys %midnights) {
defind(my $pid = fork) or die "cannot fork: $!";
if ($pid) {
## parent:
waitpid $pid, 0;
} else {
my $dir = dirname $_;
($(,$)) = ($group_id,$group_id); # (# $( : 実gid, $) : 実効gid)
($<,$>) = ($user_id,$user_id); # (# $< : 実uid, $> : 実効uid)
chdir $dir or die "cannot chdir $dir: $!";
exec "./$MIDNIGHT";
die "cannot exec $MIDNIGHT: $!";
}
}

kill 1, $httpd_pid or die "Cannot SIGHUP $httpd_pid: $!";

And then individual MIDNIGHT scripts can look like this:

そして個別の MIDNIGHT スクリプトはこのようになります:

#!/usr/bin/perl -Tw
use strict;

die "bad guy" unless getpwuid($<) =~ /^(root|nobody)$/;
my @LOGFILES = qw(access_log error_log);
umask 0;
$^I = ".".time;
@ARGV = @LOGFILES;
while (<>) {
close ARGV;
}

Can you spot the security holes? Take your time... This code shouldn't be used in hostile situations.

あなたはセキュリティホールに気づきましたか ? あせらないで... このコードは非友好的な状況で使ってはいけません.


予定外の緊急ログローテーション : Non-Scheduled Emergency Log Rotation



As we have mentioned before, there are times when the web server goes wild and starts to log lots of messages to the error_log file non-stop. If no one monitors this, it possible that in a few minutes all the free disk spaces will be filled and no process will be able to work normally. When this happens, the I/O the faulty server causes is so heavy that its sibling processes cannot serve requests.

私たちが前に述べたように, web サーバが暴走して error_log ファイルにノンストップで多量のメッセージをログし始めるときがあります. もし誰もこれをモニタしていなかったら, 数分ですべてのフリーのディスクスペースがいっぱいになりプロセスが普通に機能できなくなります. これが発生すると, 不完全なサーバが引き起こす I/O はとても重くなりその sibling (# 兄弟) プロセスはリクエストをサーブできません.
Generally this not the case, but a few people have reported to encounter this problem. If you are one of these people, you should run the monitoring program that checks the log file size and if it notices that the file has grown too large, it should attempt to restart the server and probably trim the log file.

一般にそうあることではありませんが, 何人かの人々はこの問題に遭遇したと報告しています. あなたがその人々のひとりであるなら, あなたはログファイルサイズをチェックするモニタリングプログラムを走らせる必要がありそれがファイルが大きくなりすぎていることに気づいた場合, それはそのサーバのリスタートを試みておそらくはログファイルをトリムしなければなりません.
When we have used a quite old mod_perl version, sometimes we have had bursts of an error Callback called exit showing up in our error_log. The file could grow to 300 Mbytes in a few minutes.

私たちがかなり古い mod_perl バージョンを使っていたとき, ときどき私たちは私たちの error_log で突然エラー Callback called exit の表示を持つことがありました. そのファイルは数分で 300 Mbytes になることもありました.
We will show you is an example of the script that should be executed from the crontab, to handle the situations like this. The cron job should run every few minutes or even every minute, since if you experience this problem you know that log files fills up very fast. The example script will rotate when the error_log will grow over 100K. Note that this script is useful when you have the normal scheduled log rotation facility working, remember that this one is an emergency solver and not to be used for routine log rotation.

私たちがあなたに示すのはこのよう状況を処理するために, crontab から実行されるべきスクリプトの例です. cron ジョブは数分または毎分ごとに実行するべきです, あなたがこの問題を体験しているならあなたはそのログファイルがあっというまにいっぱいになることを知っているでしょうから. この例のスクリプトは error_log が 100K を越えたときにローテートします. このスクリプトはあなたが機能する普通にスケジュールされたログローテーション機関をもっているときに便利であることに注目し, これは緊急の解決策でありルーチンのログローテーションには使わないことを覚えておいてください.

emergency_rotate.sh
-------------------
#!/bin/sh
S=`ls -s /usr/local/apache/logs/error_log | awk '{print $1}'`
if [ "$S" -gt 10000 ] ; then
mv /usr/local/apache/logs/error_log /usr/local/apache/logs/error_log.old
/etc/rc.d/init.d/httpd restart
date | /bin/mail -s "error_log $S kB on inx" admin@example.com
fi

Of course you could write a more advanced script, using the timestamps and other whistles. This example comes to illustrate how to solve the problem in question.

もちろんあなたはタイムスタンプや他のホイッスル (# 警笛, シグナル) を使って, より進んだスクリプトを書くことができます. この例は当該の問題をどのように解決するかを説明するものです.
Another solution is to use an out of box tools that are written for this purpose. The daemontools package (ftp://koobera.math.uic.edu/www/daemontools.html) includes a utility called multilog. This utility saves stdin stream to one or more log files. It optionally timestamps each line and, for each log, includes or excludes lines matching specified patterns. It automatically rotates logs to limit the amount of disk space used. If the disk fills up, it pauses and tries again, without losing any data.

他の解決策はこの目的のために書かれたすぐに使えるツールを使うことです. daemontools パッケージ (ftp://koobera.math.uic.edu/www/daemontools.html) は multilog と呼ばれるユーティリティを含みます. このユーティリティは stdin ストリームを複数の log ファイルにセーブします. これはオプションで各行のタイムスタンプ, 各ログで, 特定のパターンに一致する行を含める or 除外をします. これは使用されるディスクスペースの量を制限するために自動的にローテートします. もしディスクがいっぱいになると, それはデータを失くことなく, 停止して再トライをします.
The obvious caveat is that it doesn't restart the server, so while it tries to solve the log file handling problem it doesn't handle the originator of the problem. But since the I/O of the log writing process Apache process will be quite heavy, the rest of the servers will work very slowly if at all, and a normal watchdog should detect this abnormal situation and restart the Apache server.

明確な注意点はサーバをリスタートしないので, それがログファイル処理の問題の解決をトライする一方で問題の発生源を処理しないことです. しかしそうであったとしてもログの書込みプロセスの Apache プロセスはかなり重いので, サーバの他の部分はとてもゆっくり機能し, 通常の watchdog がこの異常事態を検知して Apache サーバをリスタートするはずです.


スワッピング防止 : Swapping Prevention



Before I delve into swapping process details, let's refresh our knowledge of memory components and memory management

私がスワッピングの詳細を掘り下げる前に, 私たちのメモリコンポートとメモリマネージメントの知識をリフレッシュしましょう
The computer memory is called RAM, which stands for Random Access Memory. Reading and writing to RAM is, by a few orders, faster than doing the same operations on a hard disk, the former uses non-movable memory cells, while the latter uses rotating magnetic media.

コンピュータメモリは RAM と呼ばれ, それは Random Access Memory (# ランダムアクセスメモリ) を表します. RAM への読込みと書込みは, 同じオペレーションをハードディスクで行うより, 数桁速く, 前者は動かないメモリセルを使う一方で, 後者は回転する磁気メディアを使います.
On most operating systems swap memory is used as an extension for RAM and not as a duplication of it. So if your OS is one of those, if you have 128MB of RAM and 256MB swap partition, you have a total of 384MB of memory available. You should never count the extra memory when you decide on the maximum number of processes to be run, and I will show why in the moment.

ほとんどのオペレーティングシステムでスワップメモリは RAM の複製ではなくその拡張として使われます. ですからあなたの OS がそのうちのひとつである場合で, あなたが 128MB の RAM と 256MB スワップパーテーションをもっているなら, あなたは合計 384MB の利用可能なメモリをもっています. あなたはあなたが実行する処理の最大値の決定するとき余分なメモリをカウントするべきではなく, 私はその理由をすぐに示します.
The swapping memory can be built of a number of hard disk partitions and swap files formatted to be used as swap memory. When you need more swap memory you can always extend it on demand as long as you have some free disk space (for more information see the mkswap and swapon manpages).

スワッピングメモリは多数のハードディスクパーテーションで構築できてスワップファイルはスワップメモリとして使われるようにフォーマットされます. あなたがより多くのスワップメモリを必要とするときあなたはあなたがフリーのディスクスペースをもっている限りは必要に応じてそれをいつでも拡張できます (詳しくは mkswap と swapon の manpage を参照してください).
System memory is quantified in units called memory pages. Usually the size of a memory page is between 1KB and 8KB. So if you have 256MB of RAM installed on your machine and the page size is 4KB your system has 64,000 main memory pages to work with and these pages are fast. If you have 256MB swap partition the system can use yet another 64,000 memory pages, but they are much slower.

システムメモリはメモリページと呼ばれるユニットで定量化されます. 通常メモリページのサイズは 1KB と 8KB の間です. ですからもしあなたがあなたのマシンでインストールされた 256MB の RAM をもっていてページサイズが 4KB だった場合あなたのシステムは機能する 64,000 のメインメモリをもっていてそれらのページは高速です. もしあなたが 256MB のスワップパーテーションをもっているならそのシステムはさらに 64,000 のメモリページを使えますが, それらはとても遅いです.
When the system is started all memory pages are available for use by the programs (processes).

システムがスタートされるとすべてのメモリページはプログラム (プロセス) が使うことができます.
Unless the program is really small, the process running this program uses only a few segments of the program, each segment mapped onto its own memory page. Therefore only a few memory pages are required to be loaded into the memory.

そのプログラムが本当に小さい場合ではない限り, このプログラムを実行するプロセスはそのプログラムのいくつかのセグメントのみを使って走り, 各セグメントはそのメモリページにマップされます. したがってメモリへのロードはわずかなメモリページだけが必要とされます.
When the process needs an additional program's segment to be loaded into the memory, it asks the system whether the page containing this segment is already loaded in the memory. If the page is not found--an event know as a page fault occurs, which requires the system to allocate a free memory page, go to the disk, read and load the requested program's segment into the allocated memory page.

プロセスが追加のプログラムのセグメントをメモリに読込むことを必要とするとき, それはこのセグメントを含むページがすでにメモリにロードされているかどうかをシステムに尋ねます. もしそのページが見つからない場合 -- ページフォルトとして知られるイベントが発生し, それはシステムにフリーのメモリページを割り当てて, ディスクに行き, 読込んでリクエストされたプログラムのセグメントを割当てられたメモリページにロードすることを要求します.
If a process needs to bring a new page into physical memory and there are no free physical pages available, the operating system must make room for this page by discarding another page from physical memory.

もしプロセスが新しいページを物理メモリに持っていく必要がありフリーの利用可能な物理ページがない場合, そのオペレーティングシステムは物理メモリから他のページを破棄してこのページのためにメイクルーム (# 場所をあける) しなければなりません.
If the page to be discarded from physical memory came from an image or data file and has not been written to then the page does not need to be saved. Instead it can be discarded and if the process needs that page again it can be brought back into memory from the image or data file.

もし物理メモリから破棄されるページがイメージ or データファイルから来ていて書込まれていないならそのページを保存する必要はありません. むしろそれは破棄されますしもしプロセスがそのページを改めて必要とする場合はそのイメージ or データファイルからメモリに連れ戻すことができます.
However, if the page has been modified, the operating system must preserve the contents of that page so that it can be accessed at a later time. This type of page is known as a dirty page and when it is removed from memory it is saved in a special sort of file called the swap file. This process is referred to as a swapping out.

しかし, ページが変更されている場合, そのオペレーティングシステムはそのページのコンテンツを後でアクセスできるように保存しなければなりません. このタイプのページはダーティページとして知られていてそれがメモリから取り除かれるとスワップファイルと呼ばれる特別なある種のファイルに保存されます. このプロセスはスワッピングアウトといわれています.
Accesses to the swap file are very long relative to the speed of the processor and physical memory and the operating system must juggle the need to write pages to disk with the need to retain them in memory to be used again.

スワップファイルへのアクセスはプロセッサや物理メモリとくらべてとても長くオペレーティングシステムはディスクにページを書込む必要とそれらをメモリで保持して再度使う必要をうまく調整しなければなりません.
In order to improve the swapping out process, to decrease the possibility that the page that has just been swapped out, will be needed at the next moment, the LRU (least recently used) or a similar algorithm is used.

スワッピングアウトプロセスを改善するため, そのスワップアウトされたばかりのページが, つぎの瞬間に必要とされる可能性を減らすために, LRU (least recently used : 直近の利用がすくない) or 同様のアルゴリズムが使われます.
To summarize the two swapping scenarios, read-only pages discarding incurs no overhead in contrast with the discarding scenario of the data pages that have been written to, since in the latter case the pages have to be written to a swap partition located on the slow disk. Therefore your machine's overall performance will be much better if there will be less memory pages that can become dirty.

この 2 つのシナリオを要約すると, リードオンリーページの破棄は書込まれたデータページを破棄するシナリオと対照的にオーバーヘッドを招きません, 後者のケースではページが遅いディスクに配置されたスワップパーテーションに書込まれなければならないためです. したがってダーティになるかもしれないメモリページがページが少なくなればあなたのマシンの全体的なパフォーマンスはとても良くなります.
But the problem is, Perl is a language with no strong data types, which means that both the program code and the program data are seen as a data pages by OS since both mapped to the same memory pages. Therefore a big chunk of your Perl code becomes dirty when its variables are modified and when the pages need to be discarded they have to be written to the swap partition.

しかし問題は, Perl が強いデータ型の言語ではないことで, それはプログラムコードとプログラムデータの両方が両方とも同じメモリページにマップされるために OS によってデータページとして見られることです. したがってあなたの Perl コードの大きな塊り (# チャンク) はその変数が変更されたときにダーティになりそのページを破棄する必要がある時にそれらはスワップパーテーションに書き込まなければなりません.
This leads us to two important conclusions about swapping and Perl.

これは私たちにスワッピングと Perl について 2 つの重要な結論を導きます.


  • Running your system when there is no free main memory available hinders performance, because processes memory pages should be discarded and then reread from disk again and again.

    利用可能なフリーのメインメモリがないときにあなたのシステムを実行するとパフォーマンスの妨げになります, なぜならプロセスメモリページは破棄されなければならずディスクから何度も再読込みしなければならないからです.


  • Since a majority of the running code is a Perl code, in addition to the overhead of reading the previously discarded pages in, the overhead of saving the dirty pages to the swap partition is occurring.

    実行中のコードの大部分が Perl コードなので, 以前に破棄されたページを読込むオーバーヘッドに加えて, スワップパーテーションにダーティページを保存するオーバーヘッドが発生します.


When the system has to swap memory pages in and out, the system slows down, not serving the processes as fast as before. This leads to an accumulation of processes waiting for their turn to run, which further causes processing demands to go up, which in turn slows down the system even more as more memory is required. This ever worsening spiral will lead the machine to halt, unless the resource demand suddenly drops down and allows the processes to catch up with their tasks and go back to normal memory usage.

システムがスワップメモリページへ出し入れしなければならないとき, システムはスローダウンし, 以前のようにプロセスを速くサーブすることができません. これは実行を待つプロセスが蓄積されることにつながり, 処理要求がさらに増すことになり, 多くのメモリが必要とされるためシステムがさらにいっそう遅くなります. この悪化し続けるスパイラルはリソース要求が突如として低下してプロセスがそのタスクをキャッチアップできるようになり通常のメモリ使用量に戻らない限りマシンを停止することにつながります.
In addition it's important to know that for a better performance, most programs, particularly programs written in Perl, on most modern OSs don't return memory pages while they are running. If some of the memory gets freed it's reused when needed by the process, without creating the additional overhead of asking the system to allocate new memory pages. That's why you will observe that Perl programs grow in size as they run and almost never shrink.

加えてベターなパフォーマンスのために, 多くのプログラム, とくに Perl で書かれたプログラムは, 多くのモダンな OS でその実行中にメモリページをリターンしない, ということを知っておくことは重要です. メモリの一部がフリーになったならばそれはプロセスに必要とされたときに再利用され, システムに新しいメモリページの割り当てを依頼するという追加のオーバーヘッドを作ることはありません. それが理由であなたは Perl プログラムが走っているとサイズが大きくなり小さくなることがほとんどないことを目の当たりにするでしょう.
When the process quits it returns its memory pages to the pool of freely available pages for other processes to use.

プロセスが終了するとそれは他のプロセスが使うためにメモリページをフリーで利用可能なページのプールにリターンします.
This scenario is certainly educating, and it should be now obvious that your system that runs the web server should never swap. It's absolutely normal for your desktop to start swapping. You will see it immediately since things will slow down and sometimes the system will freeze for a short periods. But as I've just mentioned, you can stop starting new programs and can quit some, thus allowing the system to catch up with the load and come back to use the RAM.

このシナリオは確かに教育的で, web サーバが走るあなたのシステムは決してスワップしてはならないことを明らかにしたことでしょう. あなたのデスクトップがスワップをはじめることはごく普通です. あなたはものごとが遅くなりシステムが短期的にフリーズすることになればそれをすぐにみることでしょう. しかし私がさきほど言及したように, あなたは新しいプログラムの開始をストップして一部を終了することができますので, そのシステムは負荷をキャッチアップして RAM を使えるようになります.
In the case of the web server you have much less control since it's users who load your machine by issuing requests to your server. Therefore you should configure the server, so that the maximum number of possible processes will be small enough using the MaxClients directive (For the technique for choosing the right MaxClients refer to the section 'Choosing MaxClients'). This will ensure that at peak hours the system won't swap. Remember that swap space is an emergency pool, not a resource to be used routinely. If you are low on memory and you badly need it, buy it or reduce the number of processes to prevent swapping.

web サーバのケースではあなたのマシンにリクエストを発行して負荷を掛けるのはそのユーザたちなのであなたがもつコントロールはとても少ないのです. したがって MaxClients ディレクティブを使って実行できるプロセスの最大数が十分小さくなるように, あなたはサーバを構成しなければならないはずです (正しい MacClients を選択するテクニックのために 'Choosing MaxClients' セクションを参照してください). これはピーク時にそのシステムがスワップしないことを確実するでしょう. スワップスペースが緊急のプールであり, 日常的に使われるリソースではないことを忘れないでください. もしあなたがメモリ不足でありあなたがそれをどうしても必要であるなら, スワッピングを防止するためにそれ (# メモリ) を購入するかプロセスの数を減らしてください.
However sometimes, due to the faulty code, some process might start spinning in an unconstrained loop, consuming all the available RAM and starting to heavily use swap memory. In such a situation it helps when you have a big emergency pool (i.e. lots of swap memory). But you have to resolve this problem as soon as possible since this pool won't last for a long time. In the meanwhile the Apache::Resource module can be handy.

しかしながらときおり, 杜撰なコードが原因で, 一部のプロセスが制約されないループでスピンをはじめて, すべての利用可能な RAM を消費してスワップメモリを頻繁に利用し始めることがあります. このような状況ではあなたが大きな緊急プール (i.e. 多くのスワップメモリ) をもっていると助けになります. しかしこのプールは長くは続かないのであなたはこの問題を出来る限り早急に解決しなければなりません. それまで (# 問題を解決するまで) の間 Apache::Resouce モジュールが役立ちます.
For swapping monitoring techniques see the section 'Apache::VMonitor -- Visual System and Apache Server Monitor'.

スワッピングをモニタリングするテクニックは 'Apache::VMonitor -- Visual System and Apache Server Monitor' セクションを参照してください.


mod_perl プロセスの暴走を防止する : Preventing mod_perl Processes From Going Wild



Sometimes people report that they had a problem with their code running under mod_perl that has caused all the RAM or all the disk to be used. The following tips should help you prevent these problems, before if at all they hit you.

ときおり人々は mod_perl のもとで走る彼らのコードで発生したすべての RAM or すべてのディスクが使われるという問題をリポートします. 次のチップスはそれらの問題があなたを襲うまえにそれらを防止するあなたの助けになるでしょう.


すべての RAM が消費された : All RAM Consumed



Sometimes calling an undefined subroutine in a module can cause a tight loop that consumes all the available memory. Here is a way to catch such errors. Define an UNIVERSAL::AUTOLOAD subroutine in your startup.pl, or in a <Perl></Perl> section in your httpd.conf file:

モジュールで未定義のサブルーチンを呼びだすと利用可能なすべてのメモリを消費するタイトなループが発生することがあります. こちらはそのようなエラーをキャッチする方法です. あなたの startup.pl, またはあなたの httpd.conf の <Perl></Perl> セクションで UNIVERSAL::AUTOLOAD サブルーチンを定義します.

sub UNIVERSAL::AUTOLOAD {
my $class = shift;
warn "$class can't \$UNIVERSAL::AUTOLOAD=$UNIVERSAL::AUTOLOAD!\n";
}

You can either put it in your startup.pl, or in a <Perl></Perl> section in your httpd.conf file. I do the latter. Putting it in all your mod_perl modules would be redundant (and might give you compile-time errors).

あなたはあなたの startup.pl, または httpd.conf ファイルの <Perl></Perl> セクションのどちらかにおくことができます. わたしは後者をおこないます. あなたの mod_perl モジュールすべてにこれをおくと冗長になります (それからあなたにコンパイルタイムエラーを与えるかもしれません).
This will produce a nice error in error_log, giving the line number of the call and the name of the undefined subroutine.

これは呼び出しの行番号と未定義サブルーチンの名前を与えて, error_log の中でナイスなエラーを生成します.


メンテナ : Maintainers



Maintainer is the person(s) you should contact with updates, corrections and patches.
  • Stas Bekman [http://stason.org/]



作者 : Authors



  • Stas Bekman [http://stason.org/]

Only the major authors are listed above. For contributors see the Changes file.


NEXT



次回は、「 Documentation / General Documentation / Part V: mod_perl Advocacy / mod_perl Advocacy 」を「 mod_perl 」公式サイト (https://perl.apache.org/index.html) より確認します。


参考情報は書籍「 続・初めての Perl 改訂版 」, 「 Effective Perl 第 2 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。

目次 - Perl Index


























同じカテゴリー(Perl)の記事
 Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228) (2023-10-11 23:49)
 Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227) (2023-05-26 15:41)
 Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226) (2023-05-19 17:05)
 Perl mp2 翻訳 テンプレートシステムの選択 (d225) (2022-08-15 22:23)
 Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224) (2022-06-15 20:43)
 Perl mp2 翻訳 チュートリアル (d223) (2022-06-15 20:42)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

Llama
リャマ
TI-DA
てぃーだブログ
プロフィール
セラ (perlackline)
セラ (perlackline)
QRコード
QRCODE
オーナーへメッセージ

PAGE TOP ▲