# Webサーバアーキテクチャ
## 定義
**Webサーバアーキテクチャ**とは、複数のクライアントリクエストをいかに並行処理するかを決める実装方式の選択である。根本的な問いは「1 台のサーバが同時に複数リクエストを処理するための I/O・プロセス・スレッド戦略をどう組み合わせるか」にある。(Source: [[@2015__yuuk.io__2015年Webサーバアーキテクチャ序論]])
## モデル分類
### シリアルモデル
単一プロセスがリクエストを逐次処理する。同時接続できないため、開発・テスト用途のみ。
### マルチプロセスモデル(プリフォーク)
事前に複数のワーカープロセスを生成して待機させる。
- **Copy-On-Write (COW)**: 親プロセスがメモリロード後にフォークすると、子プロセスが書き込むまでメモリページは共有される。実際のメモリ消費量はプロセス数 × サイズより大幅に小さい。
- **サンダーリングハード問題(Thundering Herd)**: 全ワーカーが同一リスニングソケットの `accept()` で起床するが成功するのは 1 つ → コンテキストスイッチ爆発。**accept mutex** で回避。
- 代表実装: Unicorn(Ruby)、Starlet(Perl)
### マルチスレッドモデル
OS レベルまたは言語ランタイムのスレッドを使用する。プロセスより生成コストが低いが、共有メモリの競合制御が必要。
### イベント駆動モデル
単一スレッドのイベントループが `select`/`poll`/`epoll`/`kqueue` でファイル記述子を多重化する。
- 理論上の同時接続上限なし(ただしファイル記述子数の OS 上限あり)
- **ブロッキング I/O が混入するとイベントループ全体が停止する**ため、ノンブロッキング I/O の徹底が必須
- 代表実装: Twiggy(Perl)、EventMachine(Ruby)、Twisted(Python)、Node.js
### ハイブリッドモデル
**マルチプロセス/スレッド + イベント駆動**:
- Nginx: マスター + ワーカープロセス(各ワーカーが `epoll`/`kqueue` で多数接続を処理)
- Play2: スレッドプール + Akka イベント駆動
**イベント駆動 + スレッド委譲**:
- EventMachine: ブロッキング処理をスレッドプールへ委譲してイベントループを空ける
- Monoceros: 単一プロセスが全接続を管理し、リクエスト処理を複数ワーカーへ委譲
## ソケット API との対応
Web サーバの核心はソケット API の操作順序:
`bind` → `listen` → `accept` → `read`/`write`
プリフォークでは親が `bind + listen`、子が並行して `accept` を担当する。
## 横断的知見
- [[@2015__yuuk.io__2015年Webサーバアーキテクチャ序論]] が示すように、モデル選択の本質は「ブロッキング I/O をどう扱うか」に帰着する。イベント駆動はブロッキングを完全に排除できる場合に最強だが、既存ライブラリがブロッキング前提で書かれていると混入を防げないという制約がある。
## 未解決の問い
- グリーンスレッド(M:N スレッドモデル・コルーチン)ベースのアーキテクチャ(Go の goroutine、Erlang プロセスなど)は上記5分類のどこに位置づけるか。@sadnessOjisan の 2023 年続編がこれを扱っているとのこと。
- ハイブリッドモデルが現代の主流になった後、さらなる進化(io_uring、eBPF など)はモデル分類にどう影響するか。
## 関連
- [[C10K問題]] — 大規模同時接続問題の定式化。イベント駆動モデルの動機。
- [[epoll]] — Linux のイベント通知機構。イベント駆動・ハイブリッドの基盤。
- [[マイクロサービスアーキテクチャ]] — 複数サービスへの分割という別の設計軸
- [[@2015__yuuk.io__2015年Webサーバアーキテクチャ序論]] — 本概念の主要出典
## 出典
- [[@2015__yuuk.io__2015年Webサーバアーキテクチャ序論]]