6 分で読了 #networking #HTTP
このページの目次

リバースプロキシとロードバランシング

リバースプロキシは単なる「リクエストの転送」ではありません——TLS 終端、キャッシュ、圧縮、レートリミット、ヘルスチェック、ブルーグリーンデプロイメントなど、現代アーキテクチャにおけるトラフィック管理はすべてこのレイヤーに集約されています。nginx/Caddy/HAProxy の設定哲学はそれぞれ異なります。

概要

リバースプロキシはサーバー側のフロントエンドです。すべての外部リクエストを受信し、TLS 終端、SNI ルーティング、レートリミット、ログ記録を行い、リクエストをバックエンドサービスに転送します。ロードバランサは、ポリシー(ラウンドロビン/最少接続/IP ハッシュなど)に基づいてリクエストを複数のバックエンドインスタンスに分散し、可用性とスループットを向上させます。Caddy は自動 TLS(ACME + Let's Encrypt のゼロコンフィグ)で知られ、nginx/HAProxy は高性能と豊富な L4/L7 機能でエンタープライズ環境を牽引しています。リバースプロキシを理解することは、インターネットサービスをデプロイする前提条件です。

リバースプロキシとフォワードプロキシ

フォワードプロキシ vs リバースプロキシ: 誰が誰を代理するか

フォワードプロキシ Client Proxy Target 例: 本体の mihomo :7890 → ブラウザのトラフィックを国外へプロキシ

リバースプロキシ Client grafana.liz6.com (Target のように見える) 実は Caddy:443 (Proxy) 127.0.0.1:3000 (Backend) Client は自分が Grafana に直接接続していると思い込んでおり、それが localhost 上にあることを知らない

フォワードプロキシは Client を助けて外部ネットワークにアクセスし、Target に対して Client を隠します。一方、リバースプロキシはその逆で、 Client に対して Target 自体であるかのように振る舞い、真の Backend を背後に隠します。

Caddy 設定

grafana.liz6.com {
    reverse_proxy 127.0.0.1:3000 {
        header_up Host {upstream_hostport}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

chat.liz6.com {
    reverse_proxy 127.0.0.1:3001
}

リバースプロキシの役割:

  1. TLS Termination: Caddy が TLS を処理 → バックエンドは HTTP → バックエンドは TLS を処理する必要がない
  2. SNI Routing: 同一ポート (443) で SNI に基づき異なるバックエンドへルーティング
  3. Request rewriting: X-Forwarded-* ヘッダーの追加、パス/ヘッダーの変更
  4. Rate Limiting: クライアントごとまたはエンドポイントごとのレートリミット
  5. Access Log: ログの一元化 (Caddy JSON アクセスログ)

L4 と L7 ロードバランシング

L4 vs L7: HTTP を解析するかどうかで、ルーティング能力と速度が決まる L4 · TCP(HTTP を解析しない) nginx stream モジュール / HAProxy mode tcp HTTP を解析しない → TCP ペイロードのみを参照 → ただし非常に高速 URL や Host ヘッダーに基づくルーティングは不可 利点: 非常に高速 生 TCP 転送や WebSocket パススルーに適している L7 · HTTP(HTTP を解析し、コンテンツに基づいてルーティング) nginx http モジュール / HAProxy mode http / Caddy HTTP を解析 → Host / URL / ヘッダー / Cookie / Method に基づいてルーティング可能 コンテンツベースのレートリミットやリクエスト検証も可能 代償: やや低速 HTTP パースのオーバーヘッド L4 と L7 のどちらを選ぶかは、コンテンツベースのルーティングが必要かどうかによる: 純粋な転送や WebSocket パススルーには速度を優先して L4 を使用し、 Host / Path / ヘッダーに基づく分散やコンテンツレベルのレートリミットを行うには、L7 を使用する必要がある。

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

ラウンドロビン:        バックエンドを順に巡回
最少接続:            接続数が最も少ないバックエンドを選択 (L7 のみ有効)
ランダム:              ランダム
IP ハッシュ:           同一クライアント IP → 同一バックエンド → スティッキー
一貫性ハッシュ:        ハッシュリング → バックエンドの増減時に 1/N だけが再ハッシュ
重み付け:              バックエンドの重み → weight=3 なら 3 倍のトラフィック

ヘルスチェック:
  パッシブ: 実際のリクエストの失敗から検出 (max_fails=N)
  アクティブ: 定期的に GET /health → 200 を期待 → 失敗時に down とマーク
  slow_start: バックエンド回復後、トラフィックを段階的に増加 (フラッディングを回避)

参考

  • Caddy: caddyserver.com/docs/caddyfile/directives/reverse_proxy
  • nginx: nginx.org/en/docs/http/ngx_http_upstream_module.html
  • HAProxy: haproxy.org

Keywords: reverse proxy, SNI routing, L4/L7 LB, health check, sticky session, rate limiting, Caddy