ウェブサイト検索

アパッチウェブサーバーのパフォーマンスを向上させるための5つのヒント


最近のNetcraftの報告によると(さまざまなサービスの中でウェブブラウザの使用統計を提供する著名なインターネット企業)、Apacheはサイトやインターネットに接続されたコンピュータの中で最も広く使用されているウェブサーバーであり続けています。

さらに、Apacheは、主要なウェブサーバーの中で最大の成長を続けており、その後にNginxとIISがあります。したがって、Apacheのインストールを管理するシステム管理者であれば、ウェブサーバーがあなたの(あるいはクライアントの)ニーズに応じてその能力を最大限に発揮する方法を知っておく必要があります。

この記事では、Apacheがスムーズに動作し、リモートクライアントから予想されるリクエストの数を処理できるようにするためのいくつかのヒントについて説明します。

しかし、Apacheはベンチマーク記録を設定するために設計されたわけではないことを心に留めておいてください。それでも、ほぼすべての使用例において高いパフォーマンスを提供することが可能です。

ヒント #1: 常にApacheを最新バージョンに更新してください

最新のバージョンのApacheをインストールすることが最初に考慮すべきことの一つであることは言うまでもありません。2015年11月19日現在、CentOS 7のリポジトリにあるApacheの最新バージョンは2.4.6であり、Debianのものは2.4.10です。

しかし、最近の改善やバグ修正が新しくリリースされた安定版に追加されている可能性があり、それがソースからダウンロードしてインストールできるようになります。ここにはコンパイルとインストールの手順も記載されています。更新方法を選択する場合は、現在の設定ファイルやサイト、仮想ホストをバックアップしておくことをお勧めします。

いずれにせよ、現在インストールされているバージョンは次のようにして確認できます:

# httpd -v               [On RedHat/CentOS based systems]
apache2 –v             [On Debian/Ubuntu based systems] 

一般的なルールとして、他に方法がない限りは、選択したディストリビューションのパッケージマネージャーが提供する更新方法(CentOSの場合はyum update httpd、Debianの場合はaptitude safe-upgrade apache2)に従ってください。最新のリリースノートはApache HTTPサーバープロジェクトのウェブサイトにあるApacheドキュメンテーションセクションで読むことができます。

ヒント #2: 2.4 より古いカーネルを使用している場合は、今すぐアップグレードを検討してください。

なぜ?カーネルバージョン2.4以上では、デフォルトでsendfileカーネルシステムコールが有効になっています。それにより、高性能なネットワークファイル転送が可能になり(これはウェブサーバーとクライアントの通信の文脈では望ましい)、Apacheは同時に読み取りと送信操作を行うことで、静的コンテンツをより迅速に、CPUの使用率を低く保ちながら配信できるようになります。

現在インストールされているカーネルを表示するには:

# uname -r

そして、これを書いている時点での最新の安定したカーネルであるwww.kernel.orgの4.3と比較してください。

初心者向けではないプロセスとはいえ、カーネルをアップグレードすることは、Linuxの内部についてもっと知るための興味深い演習です。

TIP #3: あなたのケースに最適なマルチプロセッシングモジュール(MPM)を選択してください

実際には、MPMは、Apacheのモジュール式機能を拡張し、ウェブサーバーがマシンのネットワークポートにバインドし、クライアントからのリクエストを受け入れ、リクエストを処理するために子プロセス(または代わりにスレッド)を使用する方法を決定できるようにします。

バージョン2.4から、Apacheはニーズに応じて選択できる3つの異なるMPMを提供しています:

  1. prefork MPMは、スレッドなしで複数の子プロセスを使用します。各プロセスは、個別のスレッドを作成することなく、一度に1つの接続を処理します。詳細には触れませんが、非スレッドセーフのモジュール(例えばmod_php)を使用しているアプリケーションをデバッグする場合や、アプリケーションがそれに対処する必要がある場合にのみ、このMPMを使用することをお勧めします。
  2. worker MPMは、子プロセスごとに複数のスレッドを使用し、各スレッドが1つの接続を一度に処理します。これは、高トラフィックサーバーにとって良い選択肢であり、前のケースよりも少ないRAMでより多くの同時接続を処理できるようにします。
  3. 最後に、event MPMは、バージョン2.4以上のほとんどのApacheインストールでのデフォルトのMPMです。これは、子プロセスごとに複数のスレッドを生成する点でワーカーモードのMPMと似ていますが、一つの利点があります:それは、KeepAliveやアイドル接続(それらがその状態にある間)を単一のスレッドで処理するため、他のスレッドに割り当てることができるメモリを解放します。このMPMは、mod_phpのようなスレッドセーフでないモジュールと一緒に使用するのには適しておらず、その代わりにPHP-FPMのような置き換えを使用しなければなりません。

あなたのApacheインストールで使用されているMPMを確認するには、次のようにします:

# httpd -V

下の画像は、この特定のウェブサーバーがprefork MPMを使用していることを示しています。

これを変更するには、編集する必要があります:

# /etc/httpd/conf.modules.d/00-mpm.conf          [On RedHat/CentOS based systems]
/etc/apache2/mods-available/<mpm>.load   [On Debian/Ubuntu based systems]

どこで<mpm>はmpm_event、mpm_worker、またはmpm_preforkにすることができます。

そして、次のようにして希望するモジュールをロードする行のコメントを外してください:

LoadModule mpm_event_module modules/mod_mpm_event.so

注: DebianでイベントMPMを動作させるには、非フリーリポジトリからlibapache2-mod-fastcgiパッケージをインストールする必要がある場合があります。

さらに、CentOSではphp-fpm(fcgiとmod_fcgidとともに)が必要ですが、Debianではそれはphp5-fpm(apache2-mpm-eventとともに)と呼ばれます。

最後に、ウェブサーバーと新しくインストールされたphp-fpm(またはphp5-fpm)サービスを再起動します:

RedHat/CentOSで

# systemctl restart httpd php-fpm && systemctl enable httpd php-fpm

Debian/Ubuntuで

# systemctl restart apache2 php5-fpm && systemctl enable apache2 php5-fpm

Apacheを特定のMPMを使用するように設定できますが、その設定は前述の方法と同様に、仮想ホストごとに上書きできます。

各仮想ホストの設定ファイルに対応するタグを追加するだけで、すぐに使えるようになりますが、各仮想ホストには一つだけのMPMを使用していることを確認してください。

最後に、選択したディストリビューションに関係なく、php-fpmはFastCGIの実装に依存していることに注意してください。これが、先に追加のパッケージインストールをお勧めした理由です。

php-fpm とイベント MPM がどのように連携して Apache のパフォーマンスを向上させるかについての詳細と例については、公式ドキュメントを参照してください。

これは、前の画像に表示された同じボックスで、デフォルトのMPMをpreforkからeventに変更した後に私が見るものです:

CentOS 7では、httpおよびhttpsサービスがファイアウォールを通過できるように有効になっていることを確認し、ネットワークインターフェースがデフォルトゾーンに正しく追加されている必要があります。

例えば:

# firewall-cmd --zone=internal --add-interface=tun6to4 
firewall-cmd --zone=internal --add-interface=tun6to4 --permanent 
firewall-cmd --set-default-zone=internal 
firewall-cmd --add-service=http 
firewall-cmd --add-service=https 
firewall-cmd --add-service=http --permanent 
firewall-cmd --add-service=https --permanent 
firewall-cmd --reload

私がこれを持ち出す理由は、最近クラウドVPSのデフォルトのfirewalld設定が、php-fpmとApacheがphpファイルを処理するのを妨げる問題を経験したからです。

基本的なテストとして(もっと複雑またはストレスの多いものを考えることができると思いますが)、同じハードウェア特性と負荷を持つ二つのCentOS 7サーバーの同じディレクトリにあるtest.phpという名前の別のファイルの存在を確認するphpファイルを作成します。一方はイベントを使用し、もう一方はプレフォークを使用します。

これは、checkiffileexists.phpという名前のファイルに保存したPHPコードです:

<?php
$filename = 'test.php';

if (file_exists($filename)) {
    echo "The file $filename exists";
} else {
    echo "The file $filename does not exist";
}
?>

それから、200 の同時リクエストで Apache ベンチマークツール (ab) を実行し、2000 のリクエストが完了するまで続けます:

# ab -k -c 100 -n 2000 localhost/checkiffileexists.php

テストを行い、結果を比較しましょう。パフォーマンス統計に注意してください:

ご覧のように、イベントを使用したサーバーのパフォーマンスは、このテストのすべての側面においてプリフォークのサーバーのそれを大幅に上回っています。

ヒント #4: Apache のために RAM を賢く割り当てる

考慮すべき最も重要なハードウェア項目の1つは、各Apacheプロセスに割り当てられるRAMの量です。これを直接制御することはできませんが、MaxRequestWorkersディレクティブ(以前はApache 2.2ではMaxClientsとして知られていた)を通じて子プロセスの数を制限することができ、ApacheによるRAM使用量に制限を設けることができます。再度、ホストごとまたは仮想ホストごとにこの値を設定することができます。

これを行うには、まずApacheが使用するRAMの平均量を注意深く確認し、それをMaxRequestWorkersの数で掛け算します。それがApacheプロセスのために割り当てられるメモリの量になります。ウェブサーバーに絶対に避けてほしいことの一つは、スワップを使い始めることで、そうなるとパフォーマンスが大幅に低下します。したがって、ApacheによるRAMの使用量は常に許容できる範囲内に保ち、スワップに頼らないようにするべきです。

例えば、以下のブロックは同時接続するクライアントの数を30に制限します。もしそれ以上のクライアントがホストにアクセスすると、遅延や一時的な障害が発生することがありますが、これはブラウザを再読み込みすることで簡単に解決できます。この状況は好ましくないと考えられるかもしれませんが、サーバーにはより良く、長い目で見るとあなたのサイトにとっても最善です。

このブロックは、CentOSを使用している場合は/etc/httpd/conf/httpd.conf内に、Debianを使用している場合は/etc/apache2/apache2.conf内に置くことができます。

すべてのMPMに同じ原則が適用されることに注意してください。ここでは、前のヒントで概説された概念を続けるためにイベントを使用しています:

<IfModule mpm_event_module>
    StartServers 3
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadLimit                      64
    ThreadsPerChild          25
    MaxRequestWorkers    30
    MaxConnectionsPerChild    1000
</IfModule>

いずれにせよ、選択したMPMに対して許可されているディレクティブを確認するために、Apache 2.4のドキュメントを参照することを強くお勧めします。

ヒント #5: アプリケーションを理解する

一般的に、アプリケーションを動作させるために必要のないApacheモジュールはロードしないべきです。そのためには、サーバー上で動作しているアプリケーションについての全体的な知識が必要です。特に、あなたがシステム管理者で、他のチームが開発を担当している場合はなおさらです。

現在読み込まれているモジュールをリストするには、次のコマンドを使用できます:

# httpd -M          [On RedHat/CentOS based systems]
apache2ctl -M     [On Debian/Ubuntu based systems]

CentOSでモジュールをアンロード/無効にするには、LoadModuleで始まる行をコメントアウトする必要があります(主な設定ファイルか、/etc/httpd/conf.modules.d内の補助的なファイルのどちらかにあります)。

一方で、Debian はモジュールを無効にするためのツール a2dismod を提供しており、次のように使用されます:

# a2dismod module_name

再度有効にするには:

# a2enmod module_name

いずれの場合でも、変更を適用するためにApacheを再起動することを忘れないでください。

要約

この記事では、Apacheウェブサーバーを調整し、そのパフォーマンスを向上させるのに役立つ5つのヒントをレビューしました。さらに、最適化とパフォーマンスはセキュリティがなければ無意味であることを忘れないでください。そのため、ウェブサーバーのパフォーマンスを向上させるためのmod_pagespeedのインストールや、linux-console.netのApache強化に関するヒントの記事を参照することをお勧めします。

この記事ではこのトピックのすべての側面を十分にカバーすることができないため、コミュニティの他の人と共有したいアイデアを考えてくれるかもしれません。その場合は、下のコメントフォームを使用してお気軽にお知らせください。

関連記事: