# 2015年Webサーバアーキテクチャ序論 [[Yuuki Tsubouchi]] が 2015-05-28 に公開したブログ記事(blog.yuuk.io)。Web エンジニア初心者が古典的 [[Webサーバアーキテクチャ]] を体系的に学ぶための解説記事。著者が新卒エンジニアとの会話から「体系的教材が散在していて少ない」と気づいて執筆した。 ## 概要 **核心的主張**: Web サーバアーキテクチャの根本は「並行リクエスト処理をいかに実現するか」であり、その手法は以下の系統に整理できる。 | モデル | 代表実装 | 特徴 | |--------|----------|------| | シリアル | HTTP::Server::PSGI | 開発専用・逐次処理 | | マルチプロセス(プリフォーク) | Unicorn | COW でメモリ効率化・サンダーリングハード対策必要 | | マルチスレッド | — | プロセスより軽量・共有メモリ競合あり | | イベント駆動 | Twiggy / Twisted / Node.js | 単一スレッド epoll/kqueue・ブロッキング禁止 | | ハイブリッド(プロセス+イベント) | Nginx / Play2 | 現代の主流・並行性とスループットを両立 | | ハイブリッド(イベント+スレッド) | EventMachine / Monoceros | ブロッキング処理をスレッドプールへ委譲 | ## プリフォークモデルの詳細 **Copy-On-Write (COW)**: 親プロセスがメモリをロードした後に子プロセスをフォークすると、子が書き込みを行うまでメモリページは共有される。実際のメモリ消費量は「プロセス数 × プロセスサイズ」より大幅に小さくなる。 **サンダーリングハード問題(Thundering Herd)**: 全ワーカーが同一リスニングソケットへ `accept()` を呼び出すと、カーネルが全ワーカーを起床させるが 1 つしか成功しない → 大量のコンテキストスイッチ。**accept mutex** で回避する(同時に `accept()` できるワーカーを 1 つに絞る)。 ## イベント駆動モデルの詳細 単一スレッドのイベントループが `select`/`poll`(`epoll`/`kqueue`)でファイル記述子の ready イベントを多重化する。理論上の同時接続上限なし。ただし**ブロッキング I/O が混入するとイベントループ全体が止まる**。 [[C10K問題]] への回答として [[epoll]](Linux)・`kqueue`(BSD)が設計された文脈と直結する。 ## ソケット API の役割 Web サーバの核心は次のシステムコール列: 1. `bind` — ポートにアドレスを結びつける 2. `listen` — 接続受付キューを作成 3. `accept` — クライアント接続を確立(新規通信ソケット返却) 4. `read` / `write` — リクエスト受信・レスポンス送信 プリフォーク: 親が `bind + listen`、子が並行して `accept`。 ## 学習の方針 > 「息の長い技術を優先する」 CGI → mod_xxx → FastCGI という歴史的経緯でなく、**Unix プロセスと TCP ソケットの基礎**を先に固め、Starlet → Plack 等のサーバ実装を読むことを推奨。流行り廃りのあるフレームワーク知識より基礎技術の方が長期的価値を持つ。 ## 参考文献・関連 - "UNIX ネットワークプログラミング第 2 版 Vol.1" — Stevens - "Working With TCP Sockets" — Jesse Storimer - "The C10K Problem" — Dan Kegel (https://www.kegel.com/c10k.html) - 2023 年: @sadnessOjisan が本記事を踏まえた続編を執筆(コードレベル解析・グリーンスレッド追加) ## 関連 - 著者: [[Yuuki Tsubouchi]] - 新規概念: [[Webサーバアーキテクチャ]] - 更新概念: [[C10K問題]], [[epoll]] - 関連 MOC: [[structures/SRE - MOC|SRE - MOC]]