メインコンテンツまでスキップ

Webサーバーアーキテクチャ

所要時間

約45分

学べること

  • WebサーバーがTCP接続をどう処理するか
  • WebサーバーがHTTPSをどう処理するか
  • アプリケーションとの連携方式(リバースプロキシ、組み込み等)
  • Nginx、Apache、Tomcat等の役割の違い
  • 本番環境での構成パターン

前提知識


1. Webサーバーの役割

1.1 Webサーバーとは

┌─────────────────────────────────────────────────────────────┐
│ Webサーバーが担う責務 │
├─────────────────────────────────────────────────────────────┤
│ │
│ クライアント(ブラウザ、curl等) │
│ │ │
│ │ TCP接続 │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Webサーバー │ │
│ │ │ │
│ │ 1. TCP接続の受付・管理 │ │
│ │ - ポートをLISTEN │ │
│ │ - 同時接続の管理 │ │
│ │ - Keep-Aliveの管理 │ │
│ │ │ │
│ │ 2. TLS/HTTPSの処理 │ │
│ │ - 証明書の読み込み │ │
│ │ - TLSハンドシェイク │ │
│ │ - 暗号化/復号 │ │
│ │ │ │
│ │ 3. HTTPリクエストの解析 │ │
│ │ - メソッド、パス、ヘッダーの解析 │ │
│ │ - ボディの読み取り │ │
│ │ │ │
│ │ 4. リクエストのルーティング │ │
│ │ - 静的ファイルの配信 │ │
│ │ - アプリケーションへの転送 │ │
│ │ │ │
│ │ 5. HTTPレスポンスの送信 │ │
│ │ - ヘッダー・ボディの送信 │ │
│ │ - 圧縮、キャッシュ制御 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ アプリケーション(Java, Python, Node.js等) │
│ │
└─────────────────────────────────────────────────────────────┘

1.2 代表的なWebサーバー

サーバー特徴主な用途
Nginxイベント駆動、高性能リバースプロキシ、静的ファイル配信
Apache HTTP Serverプロセス/スレッドベース、モジュール豊富汎用Webサーバー
TomcatJava Servlet コンテナJavaアプリケーション
Jetty軽量Java Servletコンテナ組み込み用途、マイクロサービス
Undertow軽量・高性能(WildFly内蔵)Spring Boot デフォルト選択肢
Node.js (http)JavaScript、シングルスレッド+イベントループAPIサーバー

2. TCP接続の処理

2.1 接続受付の仕組み

┌─────────────────────────────────────────────────────────────┐
│ Webサーバーの接続受付 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【OSレベル】 │
│ │
│ 1. socket() - ソケット作成 │
│ 2. bind() - IPアドレス:ポートに紐付け │
│ 3. listen() - 接続待ち状態に(backlogキュー作成) │
│ 4. accept() - 接続を受け入れ、新しいソケットを返す │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Listen Socket (0.0.0.0:443) │ │
│ │ │ │ │
│ │ │ accept() │ │
│ │ ▼ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Client 1 │ │Client 2 │ │Client 3 │ ... │ │
│ │ │Socket │ │Socket │ │Socket │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ │ 各クライアント接続に対して個別のソケット │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【backlogキュー】 │
│ │
│ listen(fd, backlog) の backlog: │
│ - TCP接続確立待ち(SYN_RECEIVED)のキューサイズ │
│ - accept()されるのを待っている接続のキュー │
│ │
│ net.core.somaxconn (Linux) でシステム上限を設定 │
│ │
│ キュー溢れ時: │
│ - 新規接続がドロップされる │
│ - クライアントはタイムアウト or RST │
│ │
└─────────────────────────────────────────────────────────────┘

2.2 接続処理のアーキテクチャ

┌─────────────────────────────────────────────────────────────┐
│ 接続処理のモデル比較 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【プロセスベース(Apache prefork)】 │
│ │
│ Master Process │
│ │ │
│ ├── Worker Process 1 ── Client 1 │
│ ├── Worker Process 2 ── Client 2 │
│ ├── Worker Process 3 ── Client 3 │
│ └── ... │
│ │
│ 特徴: │
│ - 各接続に1プロセス │
│ - プロセス間でメモリ分離(安定性高い) │
│ - メモリ消費大、コンテキストスイッチコスト │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【スレッドベース(Apache worker, Tomcat)】 │
│ │
│ Process │
│ │ │
│ ├── Thread 1 ── Client 1 │
│ ├── Thread 2 ── Client 2 │
│ ├── Thread 3 ── Client 3 │
│ └── ... │
│ │
│ 特徴: │
│ - 各接続に1スレッド │
│ - プロセスより軽量 │
│ - スレッドプールで上限管理 │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【イベント駆動(Nginx, Node.js)】 │
│ │
│ Worker Process │
│ │ │
│ └── Event Loop ─┬── Client 1 (fd) │
│ ├── Client 2 (fd) │
│ ├── Client 3 (fd) │
│ └── ... (数万接続可能) │
│ │
│ 特徴: │
│ - 1スレッドで多数の接続を処理 │
│ - epoll/kqueue で I/O 多重化 │
│ - ノンブロッキングI/O必須 │
│ - C10K問題を解決 │
│ │
└─────────────────────────────────────────────────────────────┘

2.3 Nginx の Worker モデル

┌─────────────────────────────────────────────────────────────┐
│ Nginx のアーキテクチャ │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Master Process (root) │ │
│ │ - 設定ファイル読み込み │ │
│ │ - Worker の起動・監視 │ │
│ │ - ログファイルオープン │ │
│ │ - 特権ポート (80, 443) のバインド │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ │ fork() │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Worker 1 │ │ Worker 2 │ │ Worker 3 │ ... │
│ │ (nginx user) │ │ (nginx user) │ │ (nginx user) │ │
│ │ │ │ │ │ │ │
│ │ Event Loop │ │ Event Loop │ │ Event Loop │ │
│ │ ├ Client A │ │ ├ Client D │ │ ├ Client G │ │
│ │ ├ Client B │ │ ├ Client E │ │ ├ Client H │ │
│ │ └ Client C │ │ └ Client F │ │ └ Client I │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ worker_processes auto; # CPUコア数に合わせて自動設定 │
│ worker_connections 1024; # 1 Worker あたりの最大接続数 │
│ │
│ 最大同時接続数 = worker_processes × worker_connections │
│ 例: 4 × 1024 = 4096 同時接続 │
│ │
└─────────────────────────────────────────────────────────────┘

3. HTTPS の処理

3.1 WebサーバーでのTLS処理

┌─────────────────────────────────────────────────────────────┐
│ WebサーバーのTLS処理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【起動時】 │
│ │
│ 1. 証明書ファイル読み込み │
│ ssl_certificate /path/to/cert.pem; │
│ ssl_certificate_key /path/to/key.pem; │
│ │
│ 2. 秘密鍵のメモリへの展開 │
│ - パスフレーズがあれば復号 │
│ - OpenSSL の SSL_CTX に設定 │
│ │
│ 3. TLS設定の初期化 │
│ - 使用するプロトコルバージョン │
│ - 暗号スイート │
│ - セッションキャッシュ │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【接続時】 │
│ │
│ Client ────────────────────────────────► Nginx │
│ │
│ 1. TCP accept() │
│ 2. SSL_accept() - TLSハンドシェイク │
│ ├── ClientHello 受信 │
│ ├── ServerHello + 証明書 送信 │
│ ├── 鍵交換 │
│ └── Finished │
│ 3. SSL_read() - 暗号化データ読み取り → 復号 │
│ 4. HTTPリクエストとして解析 │
│ 5. 処理 │
│ 6. SSL_write() - レスポンス暗号化 → 送信 │
│ │
└─────────────────────────────────────────────────────────────┘

3.2 Nginx の TLS 設定例

server {
listen 443 ssl http2;
server_name example.com;

# 証明書
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

# プロトコルバージョン
ssl_protocols TLSv1.2 TLSv1.3;

# 暗号スイート
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;

# セッション再利用(パフォーマンス向上)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off; # PFS のため無効化推奨

# OCSP Stapling(証明書失効確認の高速化)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;

# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;

location / {
proxy_pass http://backend;
}
}

3.3 TLS処理のパフォーマンス影響

┌─────────────────────────────────────────────────────────────┐
│ TLS のパフォーマンス考慮点 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【CPU負荷】 │
│ │
│ TLSハンドシェイク: │
│ - RSA 2048bit 署名: 約 1ms │
│ - ECDHE 鍵交換: 約 0.5ms │
│ - 1秒あたり数千ハンドシェイクでCPU飽和の可能性 │
│ │
│ データ暗号化/復号: │
│ - AES-NI(CPU命令)対応なら高速 │
│ - 対応していないと大きなオーバーヘッド │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【最適化】 │
│ │
│ 1. セッション再利用 │
│ - フルハンドシェイクを避ける │
│ - ssl_session_cache で設定 │
│ │
│ 2. ECDSA証明書 │
│ - RSAより署名が高速 │
│ - Let's Encrypt も ECDSA 対応 │
│ │
│ 3. TLS 1.3 │
│ - ハンドシェイク 1-RTT(1.2は2-RTT) │
│ - 0-RTT resumption(再接続時) │
│ │
│ 4. SSL アクセラレーター │
│ - 専用ハードウェアでTLS処理をオフロード │
│ - クラウドではLBがこの役割 │
│ │
└─────────────────────────────────────────────────────────────┘

3.4 誰が復号を行うか

開発者として重要な疑問: 自分が書いたコードは復号処理をしているのか?

┌─────────────────────────────────────────────────────────────┐
│ 復号を行う場所 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【パターン1: Nginx終端(本番で一般的)】 │
│ │
│ Client ──HTTPS──► Nginx ──HTTP──► Spring Boot │
│ ↓ │
│ OpenSSLが復号 │
│ │
│ アプリは平文HTTPを受け取る → アプリコードは復号しない │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【パターン2: アプリが直接HTTPS(開発環境など)】 │
│ │
│ Client ──HTTPS──► Spring Boot (port 8443) │
│ ↓ │
│ JVMが復号(JSSE) │
│ │
│ この場合でも、あなたが書いたコードは復号しない │
│ 復号するのはランタイム: │
│ - Java: JSSE(Java Secure Socket Extension) │
│ - Node.js: OpenSSLのバインディング │
│ - Go: crypto/tlsパッケージ │
│ │
└─────────────────────────────────────────────────────────────┘

コードで見る「復号が見えない」理由

// あなたが書くSpring Bootのコード
@RestController
public class UserController {

@GetMapping("/api/users")
public List<User> getUsers() {
// ← このメソッドに来た時点で、リクエストは平文
// ← TLSの復号はフレームワーク/ランタイムが済ませている
return userService.findAll();
}
}
// Node.jsでも同じ
app.get('/api/users', (req, res) => {
// ← req は既に復号済みの平文
// ← TLS処理は Node.js ランタイムが担当
res.json(users);
});

レイヤー別の責務

┌─────────────────────────────────────────────────────────────┐
│ あなたのコード(Controller, Service, Repository) │
│ → 平文のリクエスト/レスポンスしか見えない │
├─────────────────────────────────────────────────────────────┤
│ フレームワーク(Spring MVC, Express, Gin) │
│ → HTTPリクエストをパースしてハンドラに渡す │
├─────────────────────────────────────────────────────────────┤
│ ランタイムのTLS層(JSSE, OpenSSL, crypto/tls) │
│ → ★ここで復号 ★ │
├─────────────────────────────────────────────────────────────┤
│ OS(TCP/IPスタック) │
│ → 暗号化されたバイト列をソケットから読み書き │
└─────────────────────────────────────────────────────────────┘

構成別まとめ

構成復号する場所アプリコードで復号?
Nginx/Apache 終端Nginx/Apache (OpenSSL)No
クラウドLB終端AWS ALB / GCP LB 等No
アプリ直接HTTPSJVM (JSSE) / Node.js / Go ランタイムNo
TLSパススルー最終的に受けるサーバーのランタイムNo

結論: アプリケーションコード(ビジネスロジック)は復号処理を行わない。常にインフラまたはランタイムが担当する。


4. アプリケーションとの連携

4.1 連携方式の種類

┌─────────────────────────────────────────────────────────────┐
│ Webサーバーとアプリケーションの連携 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【方式1: リバースプロキシ】 │
│ │
│ Client ──► Nginx ──HTTP──► App Server (Tomcat等) │
│ └───────────────────┘ │
│ 別プロセス/別サーバー │
│ │
│ 特徴: │
│ - Webサーバーとアプリが独立 │
│ - スケーリングしやすい │
│ - 言語/フレームワーク非依存 │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【方式2: FastCGI / uWSGI】 │
│ │
│ Client ──► Nginx ──FastCGI──► PHP-FPM │
│ └─────────────────┘ │
│ 独自プロトコル │
│ │
│ 特徴: │
│ - HTTPより軽量なプロトコル │
│ - プロセスプール管理 │
│ - PHP, Python (uWSGI) で一般的 │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【方式3: 組み込み(モジュール)】 │
│ │
│ Client ──► Apache ──mod_php──► PHP │
│ └───────────────┘ │
│ 同一プロセス内 │
│ │
│ 特徴: │
│ - プロセス間通信なし(高速) │
│ - メモリ共有可能 │
│ - Webサーバーとアプリが密結合 │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【方式4: アプリ組み込みWebサーバー】 │
│ │
│ Client ──► Spring Boot (Tomcat embedded) │
│ └─────────────────────────┘ │
│ アプリ自体がWebサーバー │
│ │
│ 特徴: │
│ - デプロイが単純(jar 1つ) │
│ - アプリとサーバーが一体 │
│ - 前段にNginx/LBを置くことが多い │
│ │
└─────────────────────────────────────────────────────────────┘

4.2 リバースプロキシの詳細

┌─────────────────────────────────────────────────────────────┐
│ リバースプロキシの動作 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Client Nginx Backend │
│ │ │ │ │
│ │── TCP connect ───────►│ │ │
│ │── TLS handshake ─────►│ │ │
│ │ │ │ │
│ │── GET /api/users ────►│ │ │
│ │ │── TCP connect ───────►│ │
│ │ │ (Keep-Alive可能) │ │
│ │ │ │ │
│ │ │── GET /api/users ────►│ │
│ │ │ + X-Forwarded-For │ │
│ │ │ + X-Forwarded-Proto │ │
│ │ │ │ │
│ │ │◄── 200 OK ────────────│ │
│ │◄── 200 OK ────────────│ │ │
│ │ │ │ │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【Nginxがやっていること】 │
│ │
│ 1. クライアントからのTCP接続を受け付け │
│ 2. TLSを終端(復号) │
│ 3. HTTPリクエストを解析 │
│ 4. バックエンドへの新しいHTTP接続を作成 │
│ 5. リクエストを転送(ヘッダー追加/変更) │
│ 6. バックエンドからのレスポンスを受信 │
│ 7. クライアントへレスポンスを送信(TLS暗号化) │
│ │
└─────────────────────────────────────────────────────────────┘

4.3 Nginx リバースプロキシ設定例

upstream backend {
# ロードバランシング
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 backup;

# コネクションプール(Keep-Alive)
keepalive 32;
}

server {
listen 443 ssl http2;
server_name api.example.com;

# TLS設定(省略)

location / {
proxy_pass http://backend;

# HTTP/1.1 + Keep-Alive でバックエンド接続
proxy_http_version 1.1;
proxy_set_header Connection "";

# クライアント情報の伝播
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# タイムアウト設定
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# バッファリング
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
}

# 静的ファイルは直接配信
location /static/ {
alias /var/www/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
}

5. Spring Boot の組み込みサーバー

5.1 組み込みTomcat の動作

┌─────────────────────────────────────────────────────────────┐
│ Spring Boot 組み込み Tomcat │
├─────────────────────────────────────────────────────────────┤
│ │
│ java -jar myapp.jar │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Spring Boot Application │ │
│ │ │ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Embedded Tomcat │ │ │
│ │ │ │ │ │
│ │ │ Connector (port 8080) │ │ │
│ │ │ │ │ │ │
│ │ │ ▼ │ │ │
│ │ │ Thread Pool (default: 200 threads) │ │ │
│ │ │ │ │ │ │
│ │ │ ▼ │ │ │
│ │ │ HTTP11Processor │ │ │
│ │ │ │ │ │ │
│ │ └───────┼───────────────────────────────────────┘ │ │
│ │ ▼ │ │
│ │ DispatcherServlet │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ @RestController │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

5.2 設定例(application.yml)

server:
port: 8080

# スレッドプール設定
tomcat:
threads:
max: 200 # 最大スレッド数
min-spare: 10 # 最小スレッド数(待機)
max-connections: 8192 # 最大同時接続数
accept-count: 100 # backlogキューサイズ

# コネクション設定
connection-timeout: 20000 # 接続タイムアウト(ms)
keep-alive-timeout: 20000 # Keep-Alive タイムアウト(ms)

# HTTPSを直接処理する場合
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: ${SSL_PASSWORD}
key-store-type: PKCS12

# リバースプロキシの後ろにいる場合
forward-headers-strategy: framework

5.3 本番構成の例

┌─────────────────────────────────────────────────────────────┐
│ 本番環境の典型的な構成 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【構成1: Nginx + Spring Boot】 │
│ │
│ Internet │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ Nginx (HTTPS終端, 静的ファイル) │ ← TCP/443 │
│ └────────────────────────────────────┘ │
│ │ │
│ │ HTTP (平文) │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ Spring Boot (Tomcat embedded) │ ← TCP/8080 │
│ └────────────────────────────────────┘ │
│ │
│ Nginxの役割: │
│ - TLS終端(証明書管理) │
│ - 静的ファイル配信 │
│ - gzip圧縮 │
│ - アクセスログ │
│ - レート制限 │
│ │
│ ───────────────────────────────────────────────────────── │
│ │
│ 【構成2: クラウドLB + Spring Boot】 │
│ │
│ Internet │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────┐ │
│ │ AWS ALB (HTTPS終端) │ │
│ └────────────────────────────────────┘ │
│ │ │
│ │ HTTP │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ App Server 1│ │ App Server 2│ │ App Server 3│ │
│ │ (Spring Boot)│ │(Spring Boot)│ │(Spring Boot)│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ALBの役割: │
│ - TLS終端(ACM証明書) │
│ - ヘルスチェック │
│ - 負荷分散 │
│ - オートスケーリング連携 │
│ │
└─────────────────────────────────────────────────────────────┘

6. 接続の流れまとめ

6.1 フルスタックの接続フロー

┌─────────────────────────────────────────────────────────────┐
│ 1リクエストの完全な流れ │
├─────────────────────────────────────────────────────────────┤
│ │
│ ブラウザ: https://api.example.com/users を開く │
│ │
│ 1. DNS解決 │
│ api.example.com → 203.0.113.50 │
│ │
│ 2. TCP接続(ブラウザ → Nginx) │
│ SYN → SYN+ACK → ACK (3-way handshake) │
│ │
│ 3. TLSハンドシェイク │
│ ClientHello → ServerHello+Cert → KeyExchange → Finished │
│ ※ Nginx が証明書を返し、セッション鍵を確立 │
│ │
│ 4. HTTPリクエスト(TLS暗号化) │
│ GET /users HTTP/1.1 │
│ Host: api.example.com │
│ │
│ 5. Nginx がリクエストを解析 │
│ - TLS復号 │
│ - HTTPパース │
│ - ルーティング判定 → バックエンドへ転送 │
│ │
│ 6. バックエンド接続(Nginx → Tomcat) │
│ - コネクションプールから取得 or 新規作成 │
│ - Keep-Aliveで再利用 │
│ │
│ 7. HTTPリクエスト転送 │
│ GET /users HTTP/1.1 │
│ Host: api.example.com │
│ X-Forwarded-For: 192.0.2.10 │
│ X-Forwarded-Proto: https │
│ │
│ 8. Spring Boot 処理 │
│ - Tomcat スレッドプールからスレッド割り当て │
│ - DispatcherServlet → Controller │
│ - ビジネスロジック実行 │
│ - レスポンス生成 │
│ │
│ 9. レスポンス返却 │
│ HTTP/1.1 200 OK │
│ Content-Type: application/json │
│ {"users": [...]} │
│ │
│ 10. Nginx がレスポンスをクライアントへ │
│ - TLS暗号化 │
│ - gzip圧縮(設定時) │
│ - 送信 │
│ │
│ 11. ブラウザがレスポンス受信・表示 │
│ │
└─────────────────────────────────────────────────────────────┘

まとめ

学んだこと

  • WebサーバーがTCP接続をどう受け付け、管理するか
  • プロセス/スレッド/イベント駆動の違い
  • WebサーバーでのTLS処理の仕組み
  • アプリケーションとの連携方式(リバースプロキシ、組み込み等)
  • 本番環境での構成パターン

重要なポイント

1. TCP接続の処理
- listen() + accept() でソケット作成
- backlog キューで接続待ちを管理
- プロセス/スレッド/イベント駆動で処理

2. TLS処理
- 起動時に証明書・秘密鍵を読み込み
- 接続時にハンドシェイク
- セッション再利用でパフォーマンス向上

3. アプリ連携
- リバースプロキシ: 疎結合、スケーラブル
- 組み込み: デプロイ簡単、前段にLB/Nginxを置く
- HTTP経由が標準(FastCGIはレガシー化)

4. 本番構成
- Nginx/LB で HTTPS 終端
- 静的ファイルは Nginx から直接配信
- アプリサーバーは HTTP のみ処理

次のステップ

参考リンク