LESSON 30分

ストーリー

佐藤先輩
Webアプリにアクセスしてるけど、実はリクエストは直接アプリサーバーに届いてるわけじゃない
あなた
え?じゃあどこに届いてるんですか?
佐藤先輩
リバースプロキシだ。nginxがリクエストを受け取って、裏にいるアプリサーバーに転送してる。しかもアプリサーバーは複数台あって、ロードバランサーが振り分けてる
あなた
そんな複雑な構成になってたんですか…
佐藤先輩
これが本番環境の現実だ。この構成を理解しないと、トラブルの原因を見つけられないぞ

プロキシとは

プロキシ(Proxy)は、クライアントとサーバーの間に入って通信を仲介するサーバーです。

フォワードプロキシ

クライアント側に配置。クライアントの代わりにリクエストを送信します。

graph LR
    A["クライアント"] --> B["フォワードプロキシ"]
    B --> C["インターネット"]
    C --> D["Webサーバー"]

    classDef proxy fill:#fff3cd,stroke:#856404,color:#000
    class B proxy

用途: アクセス制限(特定サイトのブロック)、キャッシュ(同じコンテンツの高速配信)、匿名化(クライアントIPの隠蔽)

リバースプロキシ

サーバー側に配置。サーバーの代わりにリクエストを受け付けます。

graph LR
    A["クライアント"] --> B["リバースプロキシ"]
    B --> C["アプリサーバー"]

    classDef proxy fill:#fff3cd,stroke:#856404,color:#000
    class B proxy

用途: SSL終端(HTTPSの処理を代行)、ロードバランシング(複数サーバーに振り分け)、キャッシュ(静的コンテンツの高速配信)、セキュリティ(アプリサーバーを直接公開しない)


nginx - リバースプロキシの定番

nginx(エンジンエックス)は、最もよく使われるリバースプロキシ/Webサーバーです。

基本的な構成例

# /etc/nginx/sites-available/default

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;   # アプリサーバーに転送
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

構成の読み方

ディレクティブ意味
listen 80ポート80で待ち受け
server_name対象のドメイン名
proxy_pass転送先のアドレス
proxy_set_header転送時にヘッダを追加

SSL終端の例

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;   # 裏側はHTTPでOK
    }
}

nginxがHTTPSを処理し、アプリサーバーにはHTTPで転送します。これをSSL終端(SSL Termination)と呼びます。


ロードバランサー

ロードバランサーは、複数のサーバーにリクエストを振り分ける仕組みです。

なぜ必要か

graph LR
    subgraph "3台 + ロードバランサー"
        C2["クライアント"] --> LB["LB"]
        LB --> S1["サーバー1<br/>約33%"]
        LB --> S2["サーバー2<br/>約33%"]
        LB --> S3["サーバー3<br/>約33%"]
    end

    classDef lb fill:#cce5ff,stroke:#004085,color:#000
    classDef server fill:#d4edda,stroke:#28a745,color:#000
    class LB lb
    class S1,S2,S3 server

振り分けアルゴリズム

アルゴリズム動作適用場面
ラウンドロビン順番に振り分け均一なサーバー構成
最小接続数接続数が少ないサーバーに振り分け処理時間にばらつきがある場合
IPハッシュクライアントIPに基づいて固定セッション維持が必要な場合
重み付けサーバーごとに振り分け比率を設定性能が異なるサーバー構成

nginxでのロードバランシング

upstream app_servers {
    server 192.168.1.101:3000;
    server 192.168.1.102:3000;
    server 192.168.1.103:3000;
}

server {
    listen 80;

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

本番環境の典型的な構成

graph TD
    INET["インターネット"]
    CDN["CDN / WAF<br/>コンテンツ配信・攻撃防御"]
    LB["ロードバランサー<br/>リクエストの振り分け"]
    APP1["Web/App 1"]
    APP2["Web/App 2"]
    DBP[("DBプライマリ")]
    DBR[("DBレプリカ")]

    INET --> CDN --> LB
    LB --> APP1
    LB --> APP2
    APP1 --> DBP
    APP2 --> DBP
    DBR --> DBP

    classDef cdn fill:#fff3cd,stroke:#856404,color:#000
    classDef lb fill:#cce5ff,stroke:#004085,color:#000
    classDef app fill:#d4edda,stroke:#28a745,color:#000
    classDef db fill:#e2d5f1,stroke:#6f42c1,color:#000
    class CDN cdn
    class LB lb
    class APP1,APP2 app
    class DBP,DBR db

トラブルシューティングのポイント

障害がどの層で起きているかを切り分けることが重要です。

確認コマンド
CDN/WAFcurl でレスポンスヘッダのX-Cache等を確認
ロードバランサーアクセスログで振り分け先を確認
アプリサーバー各サーバーに直接アクセスして動作確認
DBDBサーバーへの接続とクエリ実行を確認

nginx のトラブルシューティング

設定のテスト

# 設定ファイルの構文チェック
sudo nginx -t

# 設定のリロード(サービス停止なし)
sudo nginx -s reload

ログの確認

# アクセスログ
tail -f /var/log/nginx/access.log

# エラーログ
tail -f /var/log/nginx/error.log

よくあるnginxエラー

エラー原因
502 Bad Gateway転送先のアプリサーバーが応答しない
504 Gateway Timeout転送先の応答が遅すぎる
403 Forbiddenパーミッションの問題

まとめ

ポイント内容
フォワードプロキシクライアント側に配置。代理でリクエスト
リバースプロキシサーバー側に配置。リクエストを受けて転送
nginxリバースプロキシ/Webサーバーの定番
SSL終端プロキシがHTTPS処理を代行
ロードバランサー複数サーバーにリクエストを振り分け

チェックリスト

  • フォワードプロキシとリバースプロキシの違いを説明できる
  • nginxの基本的な設定を読める
  • ロードバランシングの振り分け方式を3つ言える
  • 502/504エラーの原因を推測できる

次のステップへ

プロキシとロードバランサーの仕組みを理解しました。 次のセクションでは、これまで学んだ全てを使ったネットワーク障害対応の実践演習に挑戦します。


推定読了時間: 30分