<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.ja.xsl"?>
<!-- English Revision: 413452:421100 (outdated) -->

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<manualpage metafile="stopping.xml.meta">

  <title>停止と再起動</title>

<summary>
    <p>この文書では Unix に類似したシステムでの
    Apache の停止と再起動について扱っています。
    Windows NT, 2000, XP ユーザは<a
    href="platform/windows.html#winsvc">サービスとして
    Apache を実行する</a>で、Windows 9x, MEユーザは<a
    href="platform/windows.html#wincons">コンソールアプリケーションとして
    Apache を実行する</a>で、
    これらのプラットホームでの使用方法をご覧下さい。</p>
</summary>

<seealso><program>httpd</program></seealso>
<seealso><program>apachectl</program></seealso>

<section id="introduction"><title>イントロダクション</title>

    <p>Apache を停止したり再起動したりするためには、実行されている
    <program>httpd</program> プロセスにシグナルを送る必要があります。
    シグナルを送るには二つの方法があります。
    一つ目はプロセスに直接シグナルを送る unix の <code>kill</code>
    コマンドを使用する方法です。
    システムを見ればたくさんの <program>httpd</program> が
    実行されているのに気が付くでしょうが、シグナルを送るのは
    親プロセスだけで、それ以外の個々のプロセスには
    シグナルを送らないで下さい。その親プロセスの pid は
    <directive module="mpm_common">PidFile</directive>
    に書かれています。これはつまり、親以外のプロセスに
    シグナルを送る必要すらない、ということです。
    親プロセスに送ることができる 3 種類のシグナルがあります:
    <code><a href="#term">TERM</a></code>,
    <code><a href="#hup">HUP</a></code>, 
    <code><a href="#graceful">USR1</a></code>
    です。これらの説明については続きをご覧下さい。</p>

    <p>親プロセスにシグナルを送るには、
    次のようなコマンドを発行して下さい:</p>

<example>kill -TERM `cat /usr/local/apache2/logs/httpd.pid`</example>

    <p><program>httpd</program> プロセスにシグナルを送る 2 番目の方法は
    <code>-k</code> というコマンドライン引数を使用することです。
    下で説明されているように、<code>stop</code>, <code>restart</code>, 
    <code>graceful</code>, <code>graceful-stop</code> を指定できます。
    これらは <program>httpd</program> の引数ですが、
    制御用のスクリプト <program>apachectl</program> はそれらの引数をそのまま
    <program>httpd</program> に渡します。</p>

    <p><program>httpd</program> にシグナルを送った後、
    実行状況を次のコマンドで読むことができます:</p>

<example>tail -f /usr/local/apache2/logs/error_log</example>
    <p>ここに挙げた例は、各自の
    <directive module="core">ServerRoot</directive>
    と
    <directive module="mpm_common">PidFile</directive>
    の設定に適合するように適宜修正して下さい。</p>
</section>

<section id="term"><title>急な停止</title>

<dl><dt>シグナル: TERM</dt>
<dd><code>apachectl -k stop</code></dd>
</dl>

    <p><code>TERM</code> あるいは <code>stop</code> 
    シグナルを親プロセスに送ると、即座に子プロセス全てを kill しようとします。
    子プロセスを完全に kill し終わるまでに数秒かかるかもしれません。
    その後、親プロセス自身が終了します。
    処理中のリクエストは全て停止され、もはやリクエストに対する
    応答はされません。</p>
</section>

<section id="graceful"><title>緩やかな再起動 (Graceful Restart)</title>

<dl><dt>シグナル: USR1</dt>
<dd><code>apachectl -k graceful</code></dd>
</dl>

    <p>親プロセスは <code>USR1</code> あるいは <code>graceful</code>
    シグナルを受け取ると、子プロセスに現在のリクエストの処理の後に終了する
    (あるいは何もしていなければすぐに終了する)
    ように<em>助言</em>します。
    親プロセスは設定ファイルを再読込して、ログファイルを開き直します。
    子プロセスが徐々になくなるに従って、
    新しい<em>世代</em>の設定による子プロセスに置き換えていきます。
    そして、これらが新たなリクエストに即座に応答し始めます。</p>

    <p>このコードは常に
    MPM のプロセス制御ディレクティブの設定を重視しますので、
    クライアントのリクエストを扱うプロセスとスレッドの数を再起動の処理中も
    適切な値に維持されます。。また、次のようにして
    <directive module="mpm_common">StartServers</directive>
    を守ります:
    少なくとも 1 秒後に <directive
    module="mpm_common">StartServers</directive> 個の新しい子プロセスが
    生成されていなければ、その数になるように適宜プロセスを生成します。
    この挙動は現在の負荷に対して適切な子プロセスの数と
    <directive
    module="mpm_common">StartServers</directive> パラメータでの
    希望の数の両方を維持しようとしています。</p>

    <p><module>mod_status</module> を
    使用している場合は、<code>USR1</code> シグナルが送られた際に
    サーバ統計がゼロに<strong>設定されない</strong>ことに
    注意してください。
    サーバが新しいリクエストに応答不能な時間を最小にするように
    (リクエストは OS によってキューに追加されるので絶対に紛失はしません)、
    また同時に、希望のチューニングパラメータを守るように
    コードは書かれています。
    このようにするために、世代をまたがった全子プロセスの追跡に使われている
    <em>スコアボード</em>を維持しなければなりません。</p>

    <p>status モジュールは、緩やかな再起動以前から開始して
    リクエストに応答し続けている子プロセスを特定するために、
    <code>G</code> を使うこともします。</p>

    <p>現在、<code>USR1</code> を使うログ移動スクリプトでは、
    再起動前の子プロセスがログを書き終わったことを確証する方法が
    ありません。古いログに対して何かする前に、
    <code>USR1</code> シグナルを送った後いくらか適当な時間待つことを
    提案します。例えば、帯域の狭い通信路のユーザのリクエストのほとんどが 10 
    分以下で完了しているということが分かっていれば、
    古いログに何かする前に 15 分待つということです。</p>

    <note>再起動時に設定ファイルに誤りがあると、
    親プロセスは再起動せずにエラーとともに終了します。
    緩やかな再起動の場合は、親プロセスが終了した後でも子プロセスが
    実行されたまま放置されたりもします。
    (最後のリクエストを処理した後「緩やかに終了」する
    子プロセスとなります。)
    サーバを再起動する際に、これが問題になるかもしれません
    -- サーバは listen するポートにバインドできないかもしれません。
    再起動する前に、設定ファイルの構文を <code>-t</code>
    コマンドライン引数
    (<program>httpd</program> をご覧下さい)
    を使って検証することができます。
    設定ファイルの意味的な内容を構文と同様に検証したい場合は、
    非 root ユーザで <program>httpd</program> を起動しようとすればわかります。
    もしエラーがなければ、ソケットやログを開こうとして
    root でないため
    (もしくは実行中の <program>httpd</program>
    が既に必要なポートにバインドしているため)
    に失敗するでしょう。
    これ以外の理由で起動に失敗したのであれば、
    それは設定ファイルのエラーで、
    緩やかな再起動を行う前にその誤りを修正しなければなりません。</note>
</section>

<section id="hup"><title>急な再起動</title>

<dl><dt>シグナル: HUP</dt>
<dd><code>apachectl -k restart</code></dd>
</dl>

    <p><code>HUP</code> あるいは <code>restart</code> シグナルを親プロセスに送ると、
    <code>TERM</code> と同様に子プロセスを kill しますが、
    親プロセスは終了しません。
    設定ファイルを再読込して、ログファイル全てを開き直します。
    その後、新しい子プロセスを起動して応答を続けます。</p>

    <p><module>mod_status</module>
    を使っている場合は、<code>HUP</code> が送られた場合に
    サーバ統計がゼロに設定されることに注意してください。</p>

    <note>再起動時に設定ファイルに誤りがあると、
    親プロセスは再起動せずにエラーとともに終了します。
    これを避けるには次の方法をご覧下さい。</note>
</section>

<section id="gracefulstop"><title>緩やかな停止 (Graceful Stop)</title>

<dl><dt>Signal: WINCH</dt>
<dd><code>apachectl -k graceful-stop</code></dd>
</dl>

    <p>親プロセスは <code>WINCH</code> あるいは <code>graceful-stop</code>
    シグナルを受け取ると、子プロセスに現在のリクエストの処理の後に終了する
    (あるいは何もしていなければすぐに終了する)
    ように<em>助言</em>します。
    その後に親プロセスは <directive module="mpm_common">PidFile</directive>
    を削除し、全ポートからの Listen をやめます。
    親プロセスはこのまま継続し、子プロセスがリクエストを処理する
    のを監視しています。子プロセスが全て処理を終えて終了するか、<directive 
    module="mpm_common">GracefulShutdownTimeout</directive>
    で指定されたタイムアウトに達した後で、親プロセスも終了します。
    タイムアウトに達した場合は、残りの子プロセスには <code>TERM</code>
    シグナルが送信され、強制終了されます。</p>
    
    <p><code>TERM</code> シグナルによって、"graceful" 状態にある親プロセスと
    子プロセスの全てが直ちに終了します。ただし、
    <directive module="mpm_common">PidFile</directive> は既に削除
    されてしまっていますので、<code>apachectl</code> や <code>httpd</code>
    でこれらにシグナルを送ることはできません。</p>

    <note><p><code>graceful-stop</code> シグナルを使うと、まったく同一の設定
    ファイルを使った <program>httpd</program> を同時に複数起動することが
    できるようになります。
    この機能を使うと、Apache をアップグレードする際にとても便利でしょう。
    ただし、設定によってはデッドロックや競合状態 (レースコンディション) 
    を引き起こすかもしれません。</p>

    <p><directive module="core">Lockfile</directive> や <directive 
    module="mod_cgid">ScriptSock</directive> などでのディスク上のファイルについては、
    ファイルにサーバの PID が含まれるようになっていて、httpd が複数同時に動作していても
    問題がおきないように注意が払われています。
    しかし、設定ディレクティブやサードパーティ製モジュール、CGI で使用される永続的な
    ディスクを使ったロックや状態ファイルを活用している場合についても、
    複数の <program>httpd</program> が動作している状態であっても、それぞれで
    ファイルを上書きしないように注意しなければなりません。</p>

    <p>潜在的な競合状態についても心配する必要があるでしょう。
    たとえば <program>rotatelogs</program> 形式のパイプによるログなどが該当します。
    複数の <program>rotatelogs</program> インスタンスが同時に同じログファイルを
    rotate しようとすると、ログファイルが破壊されるかもしれません。</p></note>
</section>

</manualpage>
