2026年9月1日

2026年9月1日

ApacheのKeepAlive設定で接続を最適化する|MPM別の目安と確認方法

Apache の KeepAlive は、1本の TCP 接続で複数のリクエストを続けて処理する仕組みです。有効にすると画像や CSS を多く読み込むページの表示が速くなりますが、待機時間を長くしすぎると接続がサーバーの処理枠を占有し、混雑時に新しいアクセスを受け付けにくくなります。この記事では、3つの設定項目の意味、MPM ごとの考え方、CDN やロードバランサーがある構成での注意点、効いているかの確認方法を説明します。

KeepAlive が速さにつながる理由

ブラウザが Web ページを表示するとき、HTML のほかに CSS、JavaScript、画像など多数のファイルを取得します。KeepAlive が無効だと、ファイルごとに TCP 接続を張り直し、https なら TLS のやり取りもやり直します。その分だけ往復の待ち時間が増えます。

KeepAlive を有効にすると、1本の接続を使い回せるため、2つ目以降のファイルは接続確立の待ちなしで取得できます。WordPress のようにテーマやプラグインが多くのファイルを読み込むサイトでは、この差が表示速度に表れます。

一方で、サーバー側では「次のリクエストが来るかもしれない接続」を一定時間開けたまま待つことになります。この待ち時間の扱いが、設定を考えるうえでの中心になります。

3つの設定項目

KeepAlive に関係する設定は次の3つです。Apache 2.4 の既定値は、KeepAlive が On、MaxKeepAliveRequests が 100、KeepAliveTimeout が 5秒です。

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
  • KeepAlive:接続の使い回しを有効にするかどうか。通常は On のままにします。
  • MaxKeepAliveRequests:1本の接続で処理するリクエスト数の上限です。上限に達すると接続を閉じ、ブラウザは新しく接続し直します。0 は無制限を意味しますが、上限を設けておくほうが扱いやすいです。
  • KeepAliveTimeout:1つのリクエストを処理し終えてから、次のリクエストを待つ秒数です。この時間内に次のリクエストが来なければ接続を閉じます。

これらはサーバー全体か VirtualHost に書く設定で、.htaccess には書けません。Debian/Ubuntu 系では /etc/apache2/apache2.conf に記述があり、RHEL 系では /etc/httpd/conf/httpd.conf に明示されていない場合があります(その場合は既定値で動いています)。どの値が使われているかは、設定ファイルを検索すると分かります。

# Debian/Ubuntu系
grep -Rni "keepalive" /etc/apache2/
# RHEL/AlmaLinux系
grep -Rni "keepalive" /etc/httpd/

ネットワーク全般の待ち時間を決める Timeout は別の設定です。名前が似ていますが、KeepAliveTimeout は「リクエストとリクエストの間の待ち時間」、Timeout は「1つのリクエストの送受信が止まったときに待つ時間」と覚えておくと混同しません。

MPM によって最適な値が変わる

KeepAliveTimeout の影響の大きさは、Apache がどの MPM で動いているかで大きく変わります。MPM は apache2ctl -V | grep -i mpm(RHEL 系は httpd -V)で確認できます。

prefork の場合:短めにする

prefork は1接続を1プロセスで処理します。KeepAlive で次のリクエストを待っている間も、そのプロセスは他の接続を処理できません。たとえば MaxRequestWorkers が150で、KeepAliveTimeout が15秒だと、アクセスが集中したときに待機中の接続だけで処理枠が埋まり、新しい訪問者が待たされることがあります。

prefork では、KeepAlive は On のまま、KeepAliveTimeout を 2〜3秒程度に短くするのが出発点になります。ページを開いたときの一連のファイル取得は通常1〜2秒以内に終わるため、短くしても使い回しの効果はある程度残ります。

event の場合:既定値のままでよいことが多い

event MPM では、待機中の接続をリスナー用のスレッドがまとめて見張り、処理用のスレッドを占有しません。そのため KeepAliveTimeout による処理枠の圧迫は起きにくく、既定の5秒のままで問題になることは多くありません。

event でも接続そのものはサーバーのメモリとファイルディスクリプタを使います。接続数が非常に多いサイトでは、むやみに長くせず、数秒〜十数秒の範囲で様子を見ます。

HTTP/2 を使っている場合

HTTP/2 では、1本の接続の中で複数のリクエストを並行して処理します。HTTP/1.1 の KeepAlive よりも接続の使い回しの効率が高く、ブラウザが同じサイトに張る接続の本数も少なくなります。HTTP/2 の接続管理には mod_http2 側の設定も関係するため、細かな調整をする場合は使っている Apache のバージョンの mod_http2 のドキュメントを確認してください(2026年10月現在、設定項目はバージョンによって追加・変更があります)。

前段に CDN・ロードバランサーがある場合

CDN、Nginx のリバースプロキシ、クラウドのロードバランサーを Apache の前に置いている構成では、訪問者のブラウザとつながっているのは前段のサーバーです。Apache の KeepAlive は「前段と Apache の間の接続」に効きます。

この構成で気を付けたいのが、前段と Apache のタイムアウトの関係です。前段が「まだ使える」と思って再利用しようとした接続を、Apache が KeepAliveTimeout で先に閉じていると、タイミングによって 502 エラーが散発することがあります。一般には、Apache の KeepAliveTimeout を前段のアイドルタイムアウト(接続を使い回す待ち時間)より長くしておくと、この食い違いを避けられます。

たとえば AWS の Application Load Balancer は、ターゲット側の keep-alive タイムアウトをロードバランサーのアイドルタイムアウトより大きくすることを推奨しています。具体的な既定値や推奨は各サービスのドキュメントで確認してください。この場合、Apache は event MPM であれば KeepAliveTimeout を長めにしても負担が小さく済みます。prefork で長くするとプロセスが埋まりやすくなるため、MPM の見直しもあわせて検討します。

設定を変更して反映する

設定ファイルをバックアップしてから値を変更し、構文を確認してから反映します。

sudo cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.bak
sudo nano /etc/apache2/apache2.conf
sudo apachectl configtest
sudo systemctl reload apache2

Syntax OK と表示されてから reload します。KeepAlive の設定変更は reload で反映でき、処理中の接続を切らずに済みます。

効いているかを確かめる

レスポンスヘッダーで確認する

HTTP/1.1 で接続したとき、KeepAlive が有効なら Apache は応答に Keep-Alive ヘッダーを付けます。

curl -sI --http1.1 https://example.com/ | grep -i -E "^(connection|keep-alive):"

Keep-Alive: timeout=5, max=100 のように、設定した KeepAliveTimeout と MaxKeepAliveRequests の値が表示されれば反映されています。HTTP/2 で接続するとこのヘッダーは出ないため、--http1.1 を付けて確かめます。前段に CDN がある場合は、表示されるのは CDN の値なので、Apache を直接確認するにはサーバー内から http://127.0.0.1/ などに対して実行します。

接続が使い回されているかを確認する

curl に複数の URL を渡すと、同じ接続を再利用したかどうかが詳細表示に出ます。

curl -sv --http1.1 -o /dev/null -o /dev/null https://example.com/ https://example.com/robots.txt 2>&1 | grep -i "re-using"

再利用を示す行が表示されれば、KeepAlive が働いています(表示の文言は curl のバージョンによって多少異なります)。

混雑時の状態を mod_status で見る

mod_status を有効にしていれば、スコアボードで各スロットの状態を確認できます。K が KeepAlive で待機中のスロットです。prefork で K が大半を占め、空きスロット(_)がほとんど無い状態が続くなら、KeepAliveTimeout が長すぎるか、MaxRequestWorkers が足りていません。値を変えたら、アクセスの多い時間帯に再度確認し、エラーログに MaxRequestWorkers の上限に達したというメッセージが出ていないかも見ておきます。

まとめ

  • KeepAlive は1本の接続を使い回して表示を速くする仕組みで、通常は On のままにする
  • 調整の中心は KeepAliveTimeout。prefork では 2〜3秒程度に短く、event では既定値の5秒前後で十分なことが多い
  • 前段に CDN・ロードバランサーがある構成では、Apache 側のタイムアウトを前段のアイドルタイムアウトより長くして 502 を防ぐ
  • 変更後は configtest のあと reload し、curl --http1.1 の Keep-Alive ヘッダーと mod_status の K の数で効果を確かめる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲