- はじめに
- Webサーバーの性能設計の全体像
- ApacheとNginxでは処理アーキテクチャが異なる
- Apacheの並行処理を決めるMPM
- ApacheのMaxRequestWorkersを設計する
- Nginxのワーカープロセスと接続を設計する
- Keep-Aliveを設計する
- 接続受付キューを設計する
- タイムアウトを設計する
- リバースプロキシとバックエンド接続を設計する
- Apacheのバックエンド接続を設計する
- Nginxのupstream接続を設計する
- バッファリングを設計する
- ファイルディスクリプターを設計する
- WebサーバーのCPU・メモリを設計する
- Webサーバーが飽和すると何が起こるか
- 障害・縮退時の性能を設計する
- Apache / Nginxの性能試験
- Apacheの性能状態を確認する
- Nginxの性能状態を確認する
- Webサーバーのパフォーマンス設計の進め方
- まとめ
- 参考資料
はじめに
Webシステムでは、クライアントから送信されたHTTPリクエストをWebサーバーが受け付け、静的コンテンツを返したり、Tomcatなどのアプリケーションサーバーへリクエストを転送したりします。
代表的なWebサーバー / リバースプロキシとして、Apache HTTP ServerとNginxがあります。
ApacheとNginxではリクエストや接続を処理するアーキテクチャが異なるため、性能設計で確認する設定項目も異なります。一方、どちらを利用する場合でも重要になる考え方は共通しています。
Webサーバーの性能設計では、単純にワーカー数や接続数を増やすのではなく、クライアントからどれだけのリクエストを受け付け、どれだけを同時処理し、どの程度の流量をバックエンドへ渡すのかを設計することが重要です。
特に重要なのが、接続、ワーカー、キュー、KeepAlive、タイムアウト、バックエンド接続です。
本記事は、Linux上のApache HTTP Server 2.4とNginxを対象に、主にHTTP/1.1による通信を前提として性能設計を整理します。HTTP/2では1接続上で複数のストリームを並行処理できるため、接続数と同時リクエスト数を分けて確認します。HTTP/3、Webソケット、長時間のストリーミングは、通信方式に応じた追加設計が必要です。設定例の数値は関係を説明するための例であり、推奨値ではありません。
Webサーバーの性能設計の全体像
Webサーバーの性能を考えるときは、リクエストがどのような経路を通って処理されるのかを最初に整理します。

Webサーバーだけに十分な処理能力があっても、バックエンドのアプリケーションサーバーやデータベースが処理できなければ、システム全体のスループットは向上しません。
そのためWebサーバー単体の最大性能ではなく、クライアント → Webサーバー → アプリケーションサーバー → データベースというシステム全体の処理能力を考えて設計します。
ApacheとNginxでは処理アーキテクチャが異なる
ApacheとNginxの性能設計で最初に理解しておきたいのが、リクエストや接続を処理するアーキテクチャの違いです。
| 項目 | Apache | Nginx |
|---|---|---|
| 基本構造 | MPMによってプロセス / スレッドを管理 | ワーカープロセス + イベント駆動 |
| 主な処理単位 | プロセス / ワーカースレッド | ワーカープロセスが多数の接続をイベントで処理 |
| 同時処理設計 | MaxRequestWorkersなど | worker_processes / worker_connectionsなど |
| 接続管理 | MPMによって異なる | イベントループを中心に管理 |
ただし、この違いからApacheとNginxのどちらが常に高性能であると判断することはできません。ワークロード、利用するモジュール、バックエンド構成、CPU・メモリ、接続数などによって適した設計は変わります。
Apacheの並行処理を決めるMPM
ApacheではMPM(Multi-Processing Module)によって、プロセスやスレッドをどのように使って複数の接続やリクエストを処理するかが決まります。
Apache 2.4のUnix系環境で代表的なMPMには、prefork、worker、eventがあります。利用するMPMはビルド条件や配布パッケージの設定によって異なるため、実環境で確認します。
| MPM | 処理方式 | 性能設計上の特徴 |
|---|---|---|
| prefork | 複数プロセス | プロセス単位で処理するためメモリ使用量が増えやすい |
| worker | プロセス + スレッド | スレッドを利用してリクエストを並行処理 |
| event | プロセス + スレッド + イベント | Keep-Alive待機などをワーカースレッドから切り離して管理しやすい |

preforkではスレッドを使用せず、複数の子プロセスによってリクエストを処理します。同時処理数を増やすほどプロセス数も増えるため、メモリ使用量とのバランスを考える必要があります。
workerでは複数の子プロセスを起動し、それぞれのプロセス内に複数のワーカースレッドを持ちます。
eventもworkerをベースとしたプロセス + スレッド構造ですが、Keep-Aliveなどで待機している接続をワーカースレッドから切り離して扱える点が大きな特徴です。

Apache公式ドキュメントでも、event MPMは接続が実際に処理を必要とする期間を中心にワーカースレッドを使用し、Keep-Alive状態などの接続管理をリスナースレッドへ移す仕組みとして説明されています。
ApacheのMaxRequestWorkersを設計する
Apacheの性能設計で特に重要なのがMaxRequestWorkersです。
MaxRequestWorkersはApacheが同時に処理するリクエスト数の上限に関係します。preforkでは子プロセス、worker / eventではリクエストを処理するワーカースレッド数に関係します。
| 設定項目 | 役割 | 設計観点 |
|---|---|---|
| ServerLimit | プロセス数の上限に関係 | 必要以上に大きくしない |
| ThreadsPerChild | 1子プロセスあたりのスレッド数 | プロセス数との組み合わせで考える |
| ThreadLimit | ThreadsPerChildの設定可能範囲に関係 | 通常は理由なく変更しない |
| MaxRequestWorkers | 同時リクエスト処理数の上限 | CPU・メモリ・バックエンド処理能力から決める |
| MaxConnectionsPerChild | 子プロセスが終了するまでに処理する累積接続数を制限 | プロセスのライフサイクルやメモリ特性を考慮 |


worker / eventでは、MaxRequestWorkers、ServerLimit、ThreadsPerChildを個別に考えるのではなく、プロセス × スレッドという構造で設計します。
例えばMaxRequestWorkers = 400、ThreadsPerChild = 25なら、400スレッドを確保するには16個の処理用子プロセスが必要です。ServerLimitはその数を許容する値にします。MaxRequestWorkersはThreadsPerChildの整数倍で設計します。event MPMでは、再起動時に旧世代の子プロセスが残る状況も別途考慮します。詳しくはMaxRequestWorkersとevent MPMの公式資料を参照してください。
ここで重要なのは、MaxRequestWorkersを大きくすれば必ず性能が向上するわけではないことです。

例えばApacheの同時処理上限が400、Tomcatの処理スレッド数が200でも、この大小関係だけで設定の適否は判断できません。静的配信の比率、転送先の台数、非同期処理の有無、各層での処理時間によって必要な数は異なります。バックエンドへ到着する負荷が継続的に処理能力を上回る場合に、待ち時間やキューが増加します。
Apache単体の最大スループットではなく、バックエンドの処理能力を含めてMaxRequestWorkersを設計することが重要です。
Nginxのワーカープロセスと接続を設計する
Nginxではマスタープロセスの配下にワーカープロセスが起動し、それぞれのワーカープロセスがイベント駆動で多数の接続を扱います。

| 設定項目 | 役割 | 設計観点 |
|---|---|---|
| worker_processes | ワーカープロセス数 | CPU数やワークロードを考慮する |
| worker_connections | 1ワーカープロセスが同時に開ける接続数 | クライアントだけでなくバックエンド接続も含む |
| worker_rlimit_nofile | ワーカープロセスのオープンファイル上限 | ファイルディスクリプター上限との整合を確認する |
| worker_cpu_affinity | ワーカーをCPUへ割り当てる | 必要性を確認して利用する |
Nginx公式ドキュメントでは、worker_connectionsはクライアントとの接続だけではなく、プロキシ先などへの接続も含むとされています。また実際に利用できる接続数はオープンファイル上限の影響も受けます。
そのため単純に「worker_processes × worker_connections = 最大クライアント数」と考えるのではなく、バックエンド接続やファイルディスクリプターも含めて設計する必要があります。
Keep-Aliveを設計する
HTTP Keep-Aliveは、1つのTCP接続を複数のHTTPリクエストで再利用する仕組みです。

接続を再利用することで、リクエストごとにTCP接続を確立・切断するオーバーヘッドを削減できます。一方でKeep-Alive接続を長時間維持すると、ソケットやファイルディスクリプターなどのリソースを保持する時間も長くなります。
ここでいうHTTP Keep-Aliveは、OSが接続の生存確認に利用するTCP Keepaliveとは別の仕組みです。
クライアント側とバックエンド側のKeep-Aliveを分けて考える
Apache / Nginxをリバースプロキシとして利用する場合、Keep-Aliveはクライアント側とバックエンド側を分けて考えることが重要です。
※リバースプロキシ(Reverse Proxy)
クライアントからのリクエストをいったん受け取り、代理でバックエンドサーバへ転送するサーバです。

クライアント側では「Client ↔ Apache / Nginx」のTCP接続を再利用します。一方、バックエンド側では「Apache / Nginx ↔ Tomcatなどのバックエンド」の接続を再利用します。
両者は別のTCP接続です。そのため、クライアント側のKeep-Alive設定とバックエンド側の接続再利用・接続プールは、それぞれ個別に設計します。
ApacheのKeep-Alive
ApacheのKeepAlive、MaxKeepAliveRequests、KeepAliveTimeoutは、主にクライアントとApache間のHTTP持続的接続を制御します。
| 設定項目 | 役割 |
|---|---|
| KeepAlive | HTTP持続的接続を利用するか |
| MaxKeepAliveRequests | 1接続で処理できるリクエスト数 |
| KeepAliveTimeout | 次のリクエストを待つ時間 |
KeepAliveTimeoutを長くすれば接続を再利用できる可能性は高くなりますが、アイドル接続を長く保持することになります。反対に短すぎると、TCP接続の再確立が増える可能性があります。
Apacheをリバースプロキシとして利用する場合、バックエンド側の接続はmod_proxyの接続プールによって再利用できます。ProxyPassのmax、ttl、acquireなどは、このバックエンド接続の管理に関係します。詳細は後述する「Apacheのバックエンド接続を設計する」で整理します。
Apache workerとeventではKeep-Aliveの扱いが異なる
Apacheでクライアント側のKeep-Aliveを設計するときは、利用しているMPMとの関係も重要です。

worker MPMでは、Keep-Aliveで次のリクエストを待っている間も、その接続を担当するワーカースレッドが占有されます。そのため、アイドル状態のKeep-Alive接続が増えると、実際にリクエストを処理していなくても利用可能なワーカースレッドが減る可能性があります。

event MPMでは、Keep-Alive状態などの接続をワーカースレッドから切り離し、リスナースレッド側で監視できます。新しいリクエストを受信したときに処理をワーカースレッドへ渡すため、Keep-Alive待機中の接続がワーカースレッドを1対1で占有し続ける構造ではありません。
このためevent MPMでは、MaxRequestWorkersとApacheが保持できるTCP接続総数を単純に同一視しないことが重要です。
NginxのKeep-Alive
Nginxはイベント駆動型のアーキテクチャを採用しており、各ワーカープロセスがイベントループを使って多数の接続を扱います。
※イベントループ(Event Loop)
1つのWorker Processが多数の接続を効率よく処理するための仕組みです。
そのため、Keep-Aliveで次のリクエストを待っている間、接続ごとに専用のスレッドやプロセスを割り当てて待機させる構造ではありません。ワーカープロセスが接続を監視し、データが到着するとリクエスト処理を進めます。

この点は、Keep-Alive待機中もワーカースレッドを占有するApacheのworker MPMとは異なります。Apacheのevent MPMと同様に、アイドル状態のKeep-Alive接続と実際のリクエスト処理を分離しやすいアーキテクチャです。
ただし、Keep-Alive接続がリソースを消費しないわけではありません。接続を維持している間は、ソケット、ファイルディスクリプター、接続管理用のメモリ、worker_connectionsの接続枠などを使用します。
クライアント側では、keepalive_timeoutなどによってKeep-Alive接続を維持する時間を調整します。長く設定すると接続を再利用しやすくなる一方、接続枠やファイルディスクリプターを長時間保持することになります。
Nginxのupstream側Keep-Alive
Nginxをリバースプロキシとして利用する場合、バックエンド側ではupstreamへの接続を再利用できます。これは前述した「Nginx ↔ Tomcatなどのバックエンド」の接続にあたります。
Nginx 1.29.7以降では、upstreamへのKeep-Alive接続キャッシュがデフォルトで有効になっており、各ワーカープロセスあたり最大32本のアイドル接続をキャッシュします。また、HTTPプロキシではproxy_http_versionのデフォルトも1.1になっています。
ここで注意したいのは、upstreamのkeepalive 32が「バックエンドへの最大接続数は32」という意味ではないことです。keepaliveの値は、各ワーカープロセスがキャッシュとして保持するアイドル接続数の上限であり、バックエンドへの総接続数を直接制限する設定ではありません。
Nginx 1.29.7を境にデフォルト動作が変わっている点に注意します。1.29.7より前ではupstream Keep-Aliveを利用するための明示的な設定が必要でした。実際の設計では利用しているNginxのバージョンと設定内容を確認します。詳細はupstream keepaliveとproxy_http_versionの公式資料を参照してください。
接続受付キューを設計する
LinuxのTCPでは、3-way handshakeの完了を待つSYN Queueと、接続確立後にアプリケーションのaccept()を待つAccept Queueを区別します。この章で扱う「接続受付キュー」は、主に後者のAccept Queueです。既存のKeep-Alive接続上で届くHTTPリクエストが、毎回このAccept Queueに入るわけではありません。

ApacheではListenBacklogがlisten()へ渡すバックログ値に関係します。ただし実際のAccept Queueの上限は、Linuxのnet.core.somaxconnなどOS側の設定にも影響されます。SYN Queue側にはnet.ipv4.tcp_max_syn_backlogなど別の設定が関係するため、両者を混同しないようにします。
重要なのは、Accept Queueの大きさとワーカーの処理能力は別物だということです。キューを大きくしても、Webサーバーやバックエンドの処理能力そのものは増えません。処理能力が不足した状態でキューだけを大きくすると、接続をすぐに拒否せず、待ち時間を長くするだけになる場合があります。
タイムアウトを設計する
バックエンドの応答が遅いと、処理中のリクエストや接続が長く残ります。Apacheでは処理内容によってワーカースレッドも占有されます。Nginxのイベント駆動方式でも、接続枠やメモリは消費します。タイムアウトは、どの待ち時間をどこまで許容するかを決める設定です。
| 目的 | Apacheの主な設定 | Nginxの主な設定 |
|---|---|---|
| バックエンドへの接続確立待ち | ProxyPassなどのconnectiontimeout | proxy_connect_timeout |
| バックエンドとの通信待ち | ProxyTimeout/個別のtimeout | proxy_read_timeout・proxy_send_timeout |
| 次のクライアントリクエストを待つ時間 | KeepAliveTimeout | keepalive_timeout(http/server/location) |
この表は目的ごとの整理です。製品間で設定の適用範囲や計時方法は同一ではありません。ApacheのProxyTimeoutはプロキシ通信のタイムアウトを設定し、個別のプロキシワーカーではtimeoutを指定できます。接続確立の待ち時間にはconnectiontimeoutを使います。詳細はProxyPassとProxyTimeoutを確認します。
Nginxのproxy_read_timeoutはレスポンス全体の完了期限ではなく、連続する読み取り操作の間の待ち時間です。proxy_send_timeoutも連続する書き込み操作の間に適用されます。したがって、これらだけではリクエスト全体の所要時間を一定以内に制限できません。必要に応じてアプリケーション側の処理期限も設けます。Nginx公式資料
タイムアウト後もバックエンドの処理が続く場合があります。キャンセルの伝播とリトライの回数・間隔を含めて設計し、遅延時に再試行が負荷を増幅しないかを試験します。
リバースプロキシとバックエンド接続を設計する
リバースプロキシでは、クライアントから受け付ける接続と、バックエンドへ開く接続を分けて設計します。接続数、同時処理中のリクエスト数、単位時間あたりのリクエスト数は異なる指標です。

各層のスレッド数や接続プール数を同じにする必要はありません。静的配信の割合、処理時間、DB接続の保持時間、バックエンド台数を踏まえ、後段の許容負荷を超えないように調整します。前段を制限しすぎて、後段の処理能力を使い切れなくなる場合にも注意します。
Webサーバーを複数台配置する場合は、全台からバックエンドへ向かう接続と負荷を合計して確認します。接続数の上限はRPSの上限と同じではありません。受け入れ上限に達したときに、どこで待たせるか、どこでエラーを返すかも決めます。
Apacheのバックエンド接続を設計する
Apacheでは、リクエスト処理用のMaxRequestWorkersとは別に、ProxyPassなどでバックエンド接続を調整します。ここでいう「プロキシワーカー」は接続先の設定を管理する単位であり、MPMのワーカースレッドとは異なります。
| 設定 | 役割 |
|---|---|
| max | 子プロセスごとの対象接続プールの最大接続数 |
| acquire | 空き接続を待つ上限時間(ミリ秒) |
| ttl | 未使用接続を再利用する際のアイドル時間の上限(秒) |
| connectiontimeout | バックエンドへの接続確立待ち |
| timeout | 対象プロキシワーカーの通信タイムアウト |
worker/eventで子プロセスが16個あり、各プロセスの同じ接続先プールにmax=10を設定した場合、単純化した接続枠の合計は160です。max=10がApache全体の上限10を意味するわけではありません。複数のプール、Webサーバー台数、再起動中のプロセスも考慮します。preforkでは接続プールの扱いが異なるため、同じ計算をそのまま適用しません。Apache公式資料:ProxyPassの接続プール設定
Nginxのupstream接続を設計する
| 設定項目 | 役割 | 設計観点 |
|---|---|---|
| max_conns | 指定したupstreamサーバーへのアクティブ接続数を制限 | バックエンドの処理能力との整合 |
| keepalive | アイドル接続のキャッシュ | バックエンド接続再利用 |
| keepalive_requests | 1接続で処理するリクエスト数 | 接続再利用とメモリのバランス |
| keepalive_time | 同一接続でリクエストを処理できる期間 | 期間到達後、後続のリクエスト処理後に接続を閉じる |
| keepalive_timeout | アイドル状態のバックエンド接続の保持時間 | 再利用と接続保持のバランス |
注意したいのは、Nginxのupstream keepaliveのconnections値はバックエンドへの総接続数そのものを制限する設定項目ではないことです。アイドル接続のキャッシュの上限として理解する必要があります。
max_connsは、upstreamのzoneで状態を共有しない場合、ワーカープロセスごとに適用されます。例えば4ワーカーでmax_conns=100なら、条件によって合計400のアクティブ接続が可能です。zoneを使っても、アイドル接続を含む総接続数の上限が100になるわけではありません。また、別のNginxインスタンスとはこの状態を共有しません。Nginx公式資料:max_conns
バッファリングを設計する
リバースプロキシではバッファリングも性能に影響します。特にNginxでは、バックエンドから受信したレスポンスを一度バッファへ読み込みながらクライアントへ送信できます。

バッファリングを利用すると、クライアントの受信速度が遅い場合でもバックエンドからレスポンスを早めに受け取り、バックエンド接続を解放できる場合があります。ここでいうバッファは、Accept Queueなどの接続待ち行列とは別の仕組みです。
一方でバッファにはメモリを使用し、レスポンスがメモリバッファへ収まらない場合は設定によって一時ファイルへの書き込みが発生する可能性があります。そのためレスポンスサイズ、同時リクエスト数、メモリ、ストレージ I/Oを考慮して設計します。
| Nginx 設定項目 | 役割 |
|---|---|
| proxy_buffering | バックエンドレスポンスのバッファリング |
| proxy_buffer_size | レスポンス先頭部分を読み込むバッファ |
| proxy_buffers | レスポンスバッファの数とサイズ |
| proxy_max_temp_file_size | 一時ファイルの上限に関係 |
| proxy_request_buffering | クライアントリクエストボディーのバッファリング(レスポンス側とは別の設定) |
ファイルディスクリプターを設計する
Webサーバーではソケットもファイルディスクリプターを使用します。そのため大量の接続を扱う設計では、アプリケーション側の接続上限だけではなくLinux側のファイルディスクリプター上限も確認します。

Nginxではworker_connectionsを大きく設定しても、ワーカープロセスが利用できるオープンファイル数が不足していれば、その接続数を利用できません。worker_rlimit_nofileやsystemd側のLimitNOFILEなど、プロセス単位のファイルディスクリプター上限との整合が必要です。
WebサーバーのCPU・メモリを設計する
ワーカーや接続の上限を決めるときはCPUとメモリも考慮します。
ApacheではMPM、プロセス数、スレッド数、利用モジュールなどによってメモリ使用量が変化します。特にpreforkではプロセス数の増加がメモリ使用量へ影響しやすいため、MaxRequestWorkersだけを独立して決めることはできません。
Nginxでも接続、バッファ、TLS、モジュール、リクエスト / レスポンスサイズなどによってメモリ使用量が変化します。
設定項目の最大値から設計するのではなく、性能試験で1リクエスト / 接続あたりのリソース使用量やピーク時のCPU・メモリを確認し、性能余力を含めて設計します。
Webサーバーが飽和すると何が起こるか
Webサーバーの性能設計では、正常時だけではなく処理能力を超えるリクエストが到着した場合の挙動も考える必要があります。

重要なのは、「Webサーバーの飽和 = CPU使用率100%」ではないことです。
例えばバックエンドのレスポンスが遅くなると、ApacheのワーカーやWebサーバーとバックエンド間の接続が長時間占有されます。その結果、CPUに余裕があっても同時処理リソースが不足し、待ちが増加する可能性があります。応答時間がタイムアウト値を超えるとエラーとなり、クライアントや上位システムがリトライすることで、さらにリクエストが増えて負荷を増幅する場合があります。
障害・縮退時の性能を設計する
正常時に十分な性能があっても、サーバー障害によって残存サーバーへ負荷が集中すると性能要件を満たせなくなる可能性があります。

Webサーバーの台数を冗長化する場合は、1台障害時やメンテナンス時にも残存サーバーで必要なスループットを処理できるか確認します。例えば2台で通常時50%ずつ処理している構成では、1台停止時に残存サーバーへほぼ100%のリクエストが集中します。
ただし、正常時に各サーバーが50%程度の負荷だからといって、1台で必ず2倍のリクエストを処理できるとは限りません。負荷増加に対してCPU、接続、ワーカー、バックエンドなどが線形にスケールするとは限らないためです。縮退時の処理能力は机上計算だけで判断せず、実際に1台停止させた状態でも性能試験を行います。
Apache / Nginxの性能試験
設定値を決めただけでは性能設計は完了しません。想定ワークロードを与え、設計した処理能力を実際に満たせるか確認します。
| 確認項目 | 確認する内容 |
|---|---|
| スループット | RPS / TPSを満たせるか |
| 応答時間 | 平均だけでなくp95 / p99なども確認 |
| 接続 | 同時接続数と増減 |
| ワーカー | Apacheの処理スレッドやNginxの接続枠が枯渇していないか |
| キュー | 接続 / リクエスト待ちが発生していないか |
| CPU | ピーク時に性能余力があるか |
| メモリ | 接続増加時にも余力があるか |
| バックエンド | Tomcatやデータベースが先に飽和していないか |
| エラー / タイムアウト | 高負荷時にエラー率やタイムアウト数が増加していないか |
| リトライ | 再試行によって負荷が増幅していないか |
| 縮退 | 1台停止時にも性能要件を満たせるか |
Apacheの性能状態を確認する
mod_statusを利用できる環境ではBusyWorkers / IdleWorkersなどを確認し、ワーカーが上限付近まで使用されていないか確認できます。
ただしMaxRequestWorkersへ到達しているからといって、すぐに値を増やすべきとは限りません。CPU、メモリ、接続、接続受付キュー、バックエンド応答時間などを合わせて確認します。
Nginxの性能状態を確認する
Nginxでも設定値だけではなく、実際の接続数、リクエストレート、応答時間、CPU・メモリ、バックエンドの応答時間を確認します。
stub_statusを利用できる構成では、アクティブ接続やReading / Writing / Waitingなどの状態を確認できます。アクセスログには$request_timeや$upstream_response_timeなども記録します。ただし両者の差がNginx自身の処理時間を表すとは限りません。クライアントとの送受信時間やバッファリングの影響も含めて確認します。
Webサーバーのパフォーマンス設計の進め方
Webサーバーのパフォーマンス設計では、個々の設定値から決めるのではなく、性能要件とピーク負荷を起点に、処理モデル、接続、バックエンド、OSリソース、飽和時・縮退時の挙動まで順に確認します。最後に性能試験の実測値を基に、必要な箇所だけを調整します。

まとめ
Apache / Nginxのパフォーマンス設計では、単純に設定項目を大きくするのではなく、リクエストがどのように接続、ワーカー、キューを通ってバックエンドへ到達するのかを理解することが重要です。
ApacheではMPM、MaxRequestWorkers、ThreadsPerChild、KeepAlive、ListenBacklogなどが重要です。一方Nginxではworker_processes、worker_connections、ファイルディスクリプター、KeepAlive、upstream接続、バッファリングなどを確認します。
ただし、Webサーバーだけを高速化してもWebシステム全体の性能が向上するとは限りません。
クライアント → Apache / Nginx → Tomcat → データベースという一連の処理を考え、各層の処理時間と負荷配分を踏まえ、後段の許容負荷を超えないように接続数、待ち行列、タイムアウトを調整することが重要です。
Tomcat / JVM側では、スレッドプール、接続、ヒープ、GCの挙動まで確認すると、Webサーバーからデータベースまでの設計をつなげられます。
参考資料
以下は仕様を確認するための公式資料です。既定値や対応機能はバージョンによって変わるため、実際に使用するバージョンの記述も確認してください。
Apache HTTP Server 2.4
MPMの概要と選択
MPM共通設定:MaxRequestWorkers・ServerLimit・ThreadsPerChild・ListenBacklogなど
prefork MPM
worker MPM
event MPM
KeepAlive
ProxyPass:接続プール・接続確立タイムアウト
ProxyTimeout
mod_status:稼働状況の確認
Nginx
コア設定:worker_processes・worker_connections・worker_rlimit_nofileなど
クライアント側のkeepalive_timeout
プロキシ設定:通信タイムアウト・バッファリング
upstream設定:zone・max_conns・keepaliveなど
HTTP/2の設定
stub_status:接続状態の確認
アクセスログの設定
Linux・systemd
Linuxカーネル:somaxconn・TCP関連設定
Linuxカーネル:ネットワーク設定の概要
Linuxカーネル:fs.file-max / file-nr
systemd.exec:LimitNOFILEなどのリソース上限


コメント