Nginxパフォーマンスチューニング:HTTP処理と構成

12分で読めます - 2026年5月26日

hero section cover
目次
  • Nginx HTTP処理フロー:設定のチューニング
  • NginxによるHTTPリクエストの処理方法
  • ワーカプロセスと接続
  • タイムアウトとキープアライブ
  • バッファサイズ
  • ロードバランシングとアップストリームキープアライブ
  • テストと監視
共有

Nginxのワーカープロセス、バッファ、キープアライブ、ロードバランシングをチューニングして、1台のサーバーで毎秒5万件以上のリクエストを処理できるようにします。

Nginx HTTP処理フロー:設定のチューニング

Nginxのデフォルト設定は、パフォーマンスではなく互換性を重視して設計されています。適切にチューニングすれば、1台のサーバーで1秒あたり50,000~80,000件のリクエストを処理できます。本ガイドでは、最も重要な設定項目であるワーカープロセス、接続、キープアライブ、バッファリング、ロードバランシング、およびベンチマークによる変更内容の検証方法について解説します。

NginxによるHTTPリクエストの処理方法

Nginxはリクエストを明確なフェーズごとに処理し、各フェーズでシステムリソースを消費します。このフローを理解することで、適切な設定を行うことができます。

処理はカーネルレベルから始まります。着信接続はSYNおよびACCEPTキューに格納され、Nginxのワーカープロセスがそれらを取得します。接続が受け入れられると、ワーカーはカーネルバッファからHTTPリクエストを解析します。TLSトラフィックの場合、このステップではより多くのCPUリソースを消費します。

次に、NginxはHostヘッダーとIP/ポートの組み合わせを使用してリクエストを仮想サーバーにマッチングさせ、プレフィックスまたは正規表現(regex)マッチングを通じてURIをlocationブロックに解決します。

動的コンテンツの場合、Nginxはリクエストをバックエンド(FastCGI、プロキシ)に転送します。このアップストリーム通信フェーズでは、持続的接続が極めて有効です。アップストリームのキープアライブがない場合、Nginxはリクエストごとに新しいTCP接続を開くことになり、レイテンシとCPUオーバーヘッドが増加します。

もし proxy_buffering が有効になっている場合、Nginxはクライアントにレスポンスを配信する前に、アップストリームからのレスポンス全体をメモリに読み込みます。これにより、ワーカーは直ちに新しいリクエストを処理できるようになります。最後に、出力配信中に sendfile を有効にすると、ゼロコピー転送が可能になり、スループットを約6 Gbpsから30 Gbpsまで向上させることができます。

各フェーズでは、メモリバッファ、ファイルディスクリプタ、およびCPUサイクルが消費されます。以下のセクションでは、それぞれのボトルネックに対処します。

ワーカプロセスと接続

メインコンテキストで worker_processes auto; からメインコンテキストで開始してください。これにより、ワーカー数がCPUコア数と一致します。コア数が限られているVPSでは、数を手動で設定してください(例: worker_processes 2;)。ワークロードがメモリを大量に消費する場合は、RAMのオーバーコミットを避けるためにワーカー数を減らすことを検討してください。

を有効にして worker_cpu_affinity auto; を有効にすると、各ワーカーを特定のコアに固定できます。これにより、キャッシュミスやコンテキストスイッチが減少します。Nginx 1.9.10 以降で利用可能です。

接続数制限

` worker_connections ディレクティブは、各ワーカーが処理できる同時接続数を設定します。総容量は worker_processes × worker_connectionsです。デフォルトの 512 または 1,024 は本番環境では少なすぎます。トラフィックの多いサイトでは、ワーカーあたり 2,048 または 4,096 に設定してください。

各接続には、少なくとも 1 つのファイルディスクリプタが必要です。リバースプロキシ構成では、各接続が 2 つ(クライアント用とアップストリーム用)を使用します。 worker_rlimit_nofile 値の少なくとも2倍に設定し、余裕を持たせてください worker_connections 値の少なくとも2倍に設定し、余裕を持たせてください。 worker_connections 4096;の場合、 worker_rlimit_nofile 10000; 以上を使用してください。

システムレベルでは、 fs.file-max/etc/sysctl.conf を少なくとも500,000に増やし、systemdの LimitNOFILE=65535.

最後に、 multi_accept on; を events ブロックに追加し、ワーカーが保留中の接続を 1 つずつではなく一度にすべて受け入れるようにします。

タイムアウトとキープアライブ

クライアントのキープアライブ

keepalive_timeout ディレクティブは、アイドル状態のクライアント接続がどのくらいの時間開いたままになるかを制御します。トラフィックの多いサーバーの場合、30秒から65秒が適しています。2つのパラメータ形式を使用してください:

keepalive_timeout 65s 60s;

最初の値はサーバー側のタイムアウトです。2番目の値は、クライアントに対して Keep-Alive: timeout=60 ヘッダーをクライアントに送信します。クライアント側の値をわずかに低く設定することで、Nginxがすでに閉じた接続をブラウザが再利用しようとする競合状態を防ぐことができます。

この keepalive_requests ディレクティブは、1つの接続が破棄されるまでに処理できるリクエスト数の上限を設定します。デフォルトは1,000です(バージョン1.19.10で100から引き上げられました)。安定したバックエンドの場合、接続の頻繁な切り替えを減らすために、これを10,000に増やしてください。

プロキシタイムアウト

proxy_connect_timeout は、Nginxがバックエンドとの接続を確立するまで待機する時間を設定します。デフォルトは60秒です。高速なフェイルオーバーを実現するには、これを5~10秒に短縮してください。

proxy_read_timeout Nginxがアップストリームからの連続した読み取りの間に待機する時間を定義します。バックエンドの実行タイムアウトに合わせて設定してください。PHP-FPMの request_terminate_timeout が 120 秒の場合、 proxy_read_timeout を少なくとも120秒に設定し、時期尚早な504エラーを回避してください。

proxy_send_timeout アップストリームへの連続した書き込みの間隔を制御します。大きなリクエストボディを送信する場合を除き、デフォルトの60秒で通常は問題ありません。

原則として、 proxy_connect_timeout の3つの中で常に最も短い値に設定してください。

バッファサイズ

client_body_buffer_size は、Nginxがメモリ内に保持する着信リクエスト本文の量を制御します。デフォルトの8kまたは16kでは単純なフォーム送信には対応できますが、ファイルのアップロード時にはディスクに書き出されます。中小規模のアップロードには128kに増やしてください。ユーザーが大きなファイルをアップロードする場合は、 client_max_body_size ユーザーがより大きなファイルをアップロードする場合は、デフォルトの1MBから増やす必要があります。

proxy_buffer_size は、レスポンスヘッダーをボディとは別に処理します。デフォルトの4kまたは8kで通常は問題ありませんが、大きな Set-Cookie (eコマースで一般的)ではこの制限を超え、502エラーが発生する可能性があります。実際のヘッダーサイズを測定してください:

curl -s -w '%{size_header}' -o /dev/null http://your-upstream-url

4k単位に切り上げてください。

proxy_buffers レスポンスボディ用のバッファの数とサイズを設定します。デフォルト(4kまたは8kのバッファ8個、合計32k~64k)では、大きなJSONレスポンスを保持できません。 curl し、そのレスポンス全体を RAM に収めるのに十分なバッファを設定してください。

プロキシのバッファリング動作

proxy_buffering on (デフォルト)の場合、Nginxはクライアントに送信する前に、アップストリームからのレスポンス全体をメモリに読み込みます。これにより、バックエンドサーバーは直ちに新しいリクエストに対応できるようになります。

proxy_busy_buffers_size を少なくとも proxy_buffer_size 1つ分以上、かつバッファプール全体よりも少ない値に設定してください。 proxy_buffers 8 16k (合計128kの場合)、 proxy_busy_buffers_size 112k未満に保ってください。

Server-Sent Events やロングポーリングなどのリアルタイムエンドポイントについては、 proxy_buffering off ロケーション固有のブロック内で無効にします。これを /stream または /events パスに対して選択的に適用し、グローバルには適用しないでください。

ロードバランシングとアップストリームキープアライブ

デフォルトでは、Nginxはプロキシされるリクエストごとに新しいTCP接続を開きます。各ハンドシェイクには10~100msの遅延が発生し、TLSを使用する場合はさらに10~50msの遅延が加わります。アップストリームキープアライブは、このオーバーヘッドを排除するために、持続的な接続のプールを維持します。

以下の3つの設定が必要です:

upstream backend {
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    keepalive 128;
}
 
server {
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

keepalive 値は、ワーカーごとの最大アイドル接続数を設定します。最適なプールサイズは次のように計算します: (workers × target concurrency) / upstream nodes.

アップストリーム keepalive_timeout を60~120秒に設定し、バックエンドの設定に合わせ、トラフィックの急増に対応できるようにします。

負荷分散戦略

Nginxはいくつかのロードバランシング方式をサポートしています。ラウンドロビン(デフォルト)はリクエストを順番に分散させます。 least_conn は、アクティブな接続数が最も少ないサーバーにルーティングするため、リクエストの所要時間が変動するワークロードに適しています。 ip_hash は、同じクライアント IP を同じバックエンドにルーティングすることで、セッションの永続性を提供します。

サーバーの処理能力が異なる場合は、 weight パラメータを使用します:

upstream backend {
    least_conn;
    server 10.0.1.10:8080 weight=3;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080 backup;
    keepalive 128;
}

重み付けされたサーバーは、3倍のトラフィックを受け取ります。 backup サーバーは、すべてのプライマリサーバーがダウンしている場合にのみアクティブになります。 max_fails および fail_timeout をパッシブヘルスチェック用に設定し、 max_conns を使用して、バックエンドごとの同時接続数を制限します。

テストと監視

何かを変更する前には、必ずベースラインのパフォーマンスを測定してください。変更のたびに、再度ベンチマークを実施してください。変更は一度に一つずつ行ってください。

リロードする前に、 nginx -t で構文を検証してから再読み込みを行ってください。リソースの競合を避けるため、ベンチマークは別のマシンから実行してください。

wrkはHTTP負荷テストの標準ツールです:

wrk -t4 -c200 -d30s http://your-server.com/

1秒あたりのリクエスト数、平均レイテンシ、最大レイテンシ、転送レートを追跡します。Apache Benchは、より単純なテストに適しています:

ab -n 50000 -c 40 http://your-server.com/

継続的な監視

stub_status モジュールを有効にし、 curl http://localhost/nginx_status.

ログ形式にタイミング変数を追加して、遅延が発生している箇所を特定します:

  • $request_time リクエストの合計所要時間
  • $upstream_connect_time バックエンド接続時間
  • $upstream_response_time バックエンドの総処理時間

エラーログを確認し、以下の項目でバッファの問題がないか確認してください journalctl -u nginx --no-pager | grep "temporary file"。レスポンスがディスクに書き込まれている場合は、 proxy_buffers が小さすぎます。「開いているファイルが多すぎます」というエラーを探してください。これは worker_rlimit_nofile サイズを増やす必要があります。

バッファ付きロギングを使用してログ I/O を削減します:

access_log /var/log/nginx/access.log combined buffer=64k flush=5s;

負荷テスト中に ss -tn state established dst [backend_ip] を使用して、接続が再利用され、TIME_WAIT状態で蓄積されていないことを確認してください。

高性能なワークロード向けに最適化された専用サーバーおよびVPSホスティングについては、FDCサーバーをご覧ください。

ブログ

今週の特集

その他の記事
パワフルで無制限のVPSが重要な理由

パワフルで無制限のVPSが重要な理由

信頼できるパフォーマンスと無制限のトラフィックが必要ですか?強力な無制限VPSは、使用量の制限を心配することなく、必要なスピード、スケーラビリティ、帯域幅を提供します。

3分で読めます - 2025年5月9日

Linuxでストレージ容量を最適化する方法

15分で読めます - 2026年5月22日

その他の記事
background image

ご質問またはカスタムソリューションが必要ですか?

icon

柔軟なオプション

icon

グローバル・リーチ

icon

即時展開

icon

柔軟なオプション

icon

グローバル・リーチ

icon

即時展開