0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nginx × Linux × QUIC × io_uring:内部構造を体系的に理解するための完全ガイド(全14章)

0
Last updated at Posted at 2026-01-02

Nginx が「軽量で高速」と言われる理由は何か。
なぜ Apache より少ない CPU で大量の接続を捌けるのか。
そして QUIC や io_uring といった最新技術とどう関係しているのか。

この記事では、Nginx の内部構造を アーキテクチャ → I/O → HTTP → upstream → キャッシュ → QUIC → 未来 の順に体系的に整理します。

単なる設定解説ではなく、
「Nginx がどう動いているのか」
「Linux カーネルとどう連携しているのか」
「QUIC や io_uring とどうつながるのか」
を“技術書レベル”で理解できる内容です。

Nginx の内部を深く理解したいエンジニア、
パフォーマンスチューニングをしたい人、
Linux の I/O モデルを体系化したい人に向けた、
永久保存版のまとめ記事です。

目次

第1章nginx-の-アーキテクチャを理解する

Nginx を深く理解するためには、まずその「思想」を理解する必要があります。
Nginx は単なる Web サーバーではなく、OS の I/O モデル・ネットワークプロトコル・プロセス設計を徹底的に最適化した「イベント駆動型アプリケーションフレームワーク」です。

この章では、Nginx の内部構造を支える 設計思想・プロセスモデル・イベント駆動アーキテクチャ を体系的に解説します。

1.1 Nginx の設計思想

Nginx の設計思想は、次の3つに集約できます。

🔥 1. 非同期・イベント駆動モデル(Event-driven Architecture)

Nginx の最大の特徴は、1つの worker が大量の接続を同時に処理できることです。

これは「イベント駆動モデル」によって実現されています。

従来の Web サーバー(Apache MPM)の問題点

  • 1接続 = 1スレッド(または1プロセス)
  • 接続数が増えるとスレッド数が増え、コンテキストスイッチが増大
  • メモリ消費も線形に増える

Nginx のアプローチ

  • 1 worker = 1スレッド
  • epoll/kqueue による 非同期 I/O
  • イベントが発生したときだけ処理する
  • 待ち時間(I/O待ち)で CPU を浪費しない

「スレッドを増やすのではなく、イベントを効率的に処理する」
これが Nginx の高速性の根本です。

🔥 2. 少ない worker で最大のスループット

Nginx は worker を CPU コア数に合わせて起動します。

worker_processes auto;
  • 各 worker は 1 CPU コアをフルに使う
  • worker 同士は競合しないように設計されている
  • マルチスレッドではなく「マルチプロセス」
なぜ worker はスレッドではなくプロセスなのか?
  • プロセスはメモリ空間が独立 → 安定性が高い
  • 1 worker がクラッシュしても他の worker は生きている
  • セキュリティ的にも強い
    Nginx は「安定性」を最優先にした設計

🔥 3. OS の I/O モデルを最大限活用する

Nginx は Linux の以下の機能をフル活用します。

  • epoll(I/O 多重化)
  • sendfile(zero-copy)
  • TCP keepalive
  • TCP Fast Open
  • カーネルバッファの効率的利用

つまり Nginx は OS の性能を引き出すための“薄いレイヤー” として設計されています。

1.2 master / worker モデル

Nginx のプロセス構造は非常にシンプルです。

📌 図:Nginx プロセス構造

master process
 ├── worker process #1
 │     └── event loop (epoll)
 ├── worker process #2
 │     └── event loop (epoll)
 └── worker process #3
       └── event loop (epoll)

🔧 master process の役割
master は「管理者」であり、実際のリクエスト処理は行いません。

master の仕事
設定ファイルの読み込み・検証

worker の生成・終了

graceful reload(無停止リロード)

シグナル処理(HUP, TERM, QUIT)

master がリクエストを処理しない理由
master が落ちると全体が止まるため

安定性を最優先するため

🔧 worker process の役割

worker は「実働部隊」です。

worker の仕事
  • accept() で接続を受ける
  • epoll_wait() でイベントを待つ
  • HTTP リクエストを処理する
  • upstream(バックエンド)と通信する
  • 静的ファイルを返す
worker の特徴
  • 1 worker = 1 CPU コアをフル活用
  • マルチスレッドではなく シングルスレッド
  • イベントループで大量の接続を処理

🔧 worker と master の関係

master は worker を管理するだけで、
worker は完全に独立して動作します。

重要なポイント
  • worker 同士はメモリを共有しない
  • 共有が必要な場合は shared memory zone を使う
  • worker が落ちても master が再起動してくれる

Nginx の安定性は、この「プロセス分離」によって支えられている

1.3 event loop(イベントループ)の基本構造

worker は「イベントループ」を回し続けます。

while (true) {
    events = epoll_wait();
    for (event in events) {
        handler(event);
    }
}

この構造のメリット

  • I/O 待ちで CPU を浪費しない
  • 同時接続数が増えてもスレッドが増えない
  • メモリ消費が一定
  • 高負荷でも安定

1.4 Nginx が Apache より高速な理由

項目 Apache Nginx
モデル スレッド/プロセス イベント駆動
同時接続 スレッド数に依存 ほぼ無制限
メモリ消費 接続数に比例 一定
I/O ブロッキング 非同期
静的ファイル 普通 sendfile で超高速

Nginx は「スレッドを増やす」のではなく「イベントを効率的に処理する」ことで高速化している。

第1章まとめ

  • Nginx の本質は イベント駆動・非同期 I/O
  • master/worker モデルで安定性と性能を両立
  • worker は 1 CPU コアを最大活用するシングルスレッド
  • epoll によって大量の接続を効率的に処理
  • sendfile など OS の機能を最大限活用
  • Apache とは思想が根本的に違う

第2章nginxの設定読み込みとserverブロックの選択

Nginx の設定は「どのファイルがいつ読み込まれるか」を理解すると一気に整理される。

2.1 include の優先順位

Nginx は設定ファイルを 上から順番に読み込み、後勝ち で評価する。
● Debian 系の読み込み順

  1. /etc/nginx/nginx.conf
  2. include /etc/nginx/conf.d/*.conf
  3. include /etc/nginx/sites-enabled/*

● ASCII ソート順

00-aaa.conf → 10-bbb.conf → 99-zzz.conf

● 結論
sites-enabled が最も強い(最終的に読み込まれる)

2.2 server ブロックのマージルール

Nginx の設定は「内側が外側を上書きする」

http {
    server {
        location / {
        }
    }
}

優先順位は:

  1. location
  2. server
  3. http

● SSL 設定は server 単位で完結
ssl_certificate は server ブロック内の設定が絶対優先。
設定読み込み → server 選択のフロー

/etc/nginx/nginx.conf
 └── include /etc/nginx/conf.d/*.conf
      └── include /etc/nginx/sites-enabled/*
           └── server blocks (default_server / SSL / location)

2.3 default_server の仕組み

複数のserverブロックが同じポートをlistenしている場合、どれを使うかを決める仕組みが必要。

それがdefault_server

● default_server が選ばれる条件

  • Host ヘッダが無い
  • Host がどの server_name にも一致しない
  • HTTPS の SNI が無い

● 結論
default_server は「最後の受け皿」

第3章server_name のマッチングとlocationの決定

Nginxの仮想ホスト選択は、server_name → location の順で決まる。

3.1 server_name の優先順位

Nginx は server_name を次の順で評価する

  1. 完全一致(exact)
  2. ワイルドカード(前方一致)
  3. ワイルドカード(後方一致)
  4. 正規表現(regex)
  5. default_server

3.2 server_name_hash の内部構造

大量のserver_nameを高速に検索するため、Nginxはハッシュテーブル を使う

  • 起動時に server_name をハッシュ化
  • Host ヘッダをハッシュ化
  • O(1) で検索

● 調整パラメータ

server_names_hash_bucket_size
server_names_hash_max_size

3.3 location マッチングの優先順位

location は次の順で評価される。

  1. exact (=)
  2. prefix(最長一致)
  3. regex(最終勝利)

● 例

location = /about
location /about
location /about/team
location ~ ^/about/[0-9]+$

/about/123 → regex が勝つ

server_name → location 決定フロー

Host ヘッダ
 ├── 完全一致 (exact)
 ├── ワイルドカード一致 (prefix/suffix)
 ├── 正規表現一致 (regex)
 └── default_server

location マッチング
 ├── exact (= /about)
 ├── prefix (/about/)
 └── regex (~ ^/about/[0-9]+$)

第3章まとめ

  • server_name → location の順で決まる
  • server_name はハッシュで高速検索
  • location は exact → prefix → regex
  • default_server は最後の受け皿

第4章nginxの内部処理フェーズ(phase handler)

4.1 フェーズ一覧
post-read

server rewrite

find config

location rewrite

access

try_files

content

log

4.2 rewrite と return の優先順位
return は即時終了

rewrite は URL 書き換えのみ

4.3 try_files の評価順
静的ファイル → ディレクトリ → fallback

rewrite より後、content handler より前

📌 図:Nginx リクエスト処理フェーズ

第5章イベントループと epoll/kqueue の内部

5.1 epoll の基本
epoll_ctl

epoll_wait

readiness model

5.2 Nginx の event loop
handler の種類

multi-event

accept mutex

5.3 kqueue / event ports との違い
📌 図:epoll イベントループ

第6章upstreamの内部構造とロードバランシング

6.1 proxy_pass の内部処理
upstream 選択

非同期接続

ストリーミング転送

keepalive 再利用

6.2 upstream keepalive の内部構造
worker ローカルの接続プール

idle / busy / expired

FD は worker 間で共有不可

6.3 ロードバランシングアルゴリズム
round robin

least_conn

ip_hash

hash(consistent)

📌 図:upstream keepalive プール構造

第7章proxy_cacheの内部構造とLRU

7.1 ディスク構造
ハッシュベースの階層

ext4/XFS の最適化

7.2 shared memory のメタデータ
key

expire

size

disk path

LRU リンク

7.3 LRU の実装
近似 LRU

末尾削除

ディスク削除

📌 図:proxy_cache(メモリ+ディスク)

第8章レート制限(limit_req)の内部

8.1 トークンバケット方式
tokens/sec

burst

503 の条件

8.2 shared memory zone の役割
ハッシュテーブル

排他制御(spinlock)

📌 図:トークンバケット

第9章zero-copy I/O の進化(sendfile → splice → io_uring)

9.1 sendfile
ファイル → カーネル → NIC

静的ファイル配信に最適

9.2 splice
pipe 経由の zero-copy

汎用性が高い

9.3 io_uring
SQ/CQ リング

完全非同期

syscall 削減

sendfile の置き換え候補

📌 図:sendfile / splice / io_uring 比較

第10章HTTP/2 と QUIC(HTTP/3)の内部構造

10.1 HTTP/2 のストリーム多重化
フレーム

ストリーム ID

優先度制御

10.2 QUIC のパケット構造
Connection ID

Packet Number

暗号化された payload

10.3 loss detection(RFC9002)
ACK range

packet number space

タイムベース

パケットベース

10.4 フロー制御
ストリーム単位

接続全体

📌 図:QUIC ストリーム構造

第11章nginx の timer wheel

11.1 タイマー管理の課題
keepalive timeout

request timeout

大量のタイマー

11.2 timer wheel の構造
スロット

リスト

O(1) 近い性能

📌 図:timer wheel

第12章nginx ソースコードの読み方ガイド

12.1 event 系
ngx_event.c

ngx_event_epoll.c

ngx_event_timer.c

12.2 http 系
ngx_http_request.c

ngx_http_upstream.c

ngx_http_file_cache.c

ngx_http_limit_req_module.c

12.3 読む順番のおすすめ

第13章nginxの未来io_uring/QUIC

13.1 epoll から io_uring への移行可能性
13.2 QUIC ネイティブサポートの課題
13.3 Nginx Plus と OSS の違い
🏁 第14章:まとめ(永久保存版)
Nginx の高速性の正体

Linux カーネルとの連携

QUIC と io_uring の未来

全体を貫く「イベント駆動」の思想

第14章まとめNginxの内部構造を理解するということ

Nginx の内部構造を体系的に理解すると、
設定ファイルの意味が「暗記」から「理解」に変わります。

  • なぜイベント駆動が高速なのか
  • なぜ upstream がブロックしないのか
  • なぜキャッシュが高速なのか
  • なぜ QUIC が HTTP/2 を超えるのか
  • なぜ io_uring が次世代 I/O と呼ばれるのか
    これらはすべて、
    Nginx が Linux カーネルの設計思想と深く結びついているからです。

Nginx は単なる Web サーバーではなく、
「OS とネットワークの設計美をそのまま体現したソフトウェア」です。

この記事が、
Nginx の内部構造を深く理解するための
永久保存版のリファレンスになれば幸いです。

もしこの記事が役に立ったら、
スターやフォローをしていただけると励みになります。

また、続編として Nginx のセキュリティ設計 / HTTP/2 の内部 / QUIC の実装解説 なども書く予定です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?