目次

スケールアウト構成でWebサービスを運営する際、複数のサーバーへトラフィックを分散するロードバランサーは欠かせないコンポーネントだ。単なるトラフィック分散装置にとどまらず、ヘルスチェック、SSL終端、セッション管理など多くの役割を担う。本稿ではロードバランサーの仕組みを技術レイヤーから理解し、代表的な分散アルゴリズムと設計パターンを解説する。

なぜロードバランサーが必要か

単一サーバーでWebサービスを運営する場合、アクセスが集中するとサーバーのCPUやメモリが枯渇し、レスポンスタイムが悪化する。サーバーがクラッシュすれば完全なサービス停止(SPOF: 単一障害点)になる。

ロードバランサーはこの問題を解決する。

  • 負荷分散: 複数のサーバーにリクエストを分散し、特定サーバーへの集中を防ぐ
  • 可用性向上: 1台がダウンしても他のサーバーが処理を引き継ぐ
  • スケーラビリティ: サーバーを追加するだけで処理能力を線形に拡張できる
  • メンテナンス容易性: サーバーを1台ずつローリングアップデートできる

L4とL7の違い

ロードバランサーはOSIモデルのどの層で動作するかによって大きく分類される。

L4ロードバランサー(トランスポート層)

TCP/UDPレイヤーでパケットをルーティングする。パケットの中身(HTTPヘッダーなど)を読まずに、IPアドレスとポート番号だけを見て転送先を決定する。

クライアント
    │ TCP接続
    ▼
[L4 LB: 203.0.113.1:443]
    │
    ├──→ サーバーA: 192.168.1.10:443
    ├──→ サーバーB: 192.168.1.11:443
    └──→ サーバーC: 192.168.1.12:443

特徴:

  • 処理が軽量で超高スループット(数百万接続/秒が可能)
  • HTTPの中身を解析しないのでSSLの中身は見えない
  • パスベースルーティングやHostヘッダーによる振り分けは不可
  • AWS NLB、HAProxy(TCPモード)などが代表例

L7ロードバランサー(アプリケーション層)

HTTPリクエストの内容(URL、ヘッダー、クッキー、リクエストボディ)を解析して転送先を決定する。より高度なルーティングが可能だが、処理コストはL4より高い。

クライアント
    │ HTTPS
    ▼
[L7 LB: SSL終端 + HTTPパース]
    │
    ├── /api/* → バックエンドサーバー群
    ├── /static/* → 静的ファイルサーバー
    └── /admin/* → 管理サーバー(IP制限付き)

特徴:

  • URLパス、HTTPヘッダー、クッキーに基づいた高度なルーティング
  • SSL終端(サーバー側はHTTPで通信できる)
  • リクエスト/レスポンスの書き換えやヘッダー追加
  • AWS ALB、nginx、Envoy、Traefikなどが代表例

使い分け

判断基準L4L7
スループット最優先
パスベースルーティングが必要
マイクロサービス間通信
SSL終端をLBで行いたい
非HTTP(DBなど)のプロキシ

分散アルゴリズム

ロードバランサーがどのサーバーにリクエストを転送するかは、設定されたアルゴリズムによって決まる。

ラウンドロビン(Round Robin)

最もシンプルなアルゴリズム。サーバーを順番に選択し、全サーバーへ均等にリクエストを分配する。

リクエスト1 → サーバーA
リクエスト2 → サーバーB
リクエスト3 → サーバーC
リクエスト4 → サーバーA(最初に戻る)

適した場面: サーバーのスペックが均一で、各リクエストの処理時間も均一な場合。問題点: 処理が重いリクエストが特定サーバーに集中すると、そのサーバーだけ過負荷になる。

加重ラウンドロビン(Weighted Round Robin)

サーバーごとに重みを設定し、スペックの違いを考慮する。

サーバーA(重み: 3)→ 3回に1回
サーバーB(重み: 2)→ 5回に2回
サーバーC(重み: 1)→ 6回に1回

スペックが異なるサーバー(例: 旧マシンと新マシンが混在)を扱う場合に有効だ。

Least Connections(最小接続数)

現在の接続数が最も少ないサーバーを選択する。接続を維持するWebSocketや、処理時間が大きくばらつくAPIに適している。

def select_server(servers):
    return min(servers, key=lambda s: s.active_connections)

IP Hash

クライアントのIPアドレスをハッシュ化して、常に同じサーバーへ転送する(スティッキーセッション)。セッション情報をサーバー側で持つ場合に必要になる。

クライアントIP: 203.0.113.50
hash(203.0.113.50) % 3 = 1 → 常にサーバーBへ

注意: クライアントが同じNAT(企業ネットワーク等)の背後にいる場合、1台のサーバーに集中するリスクがある。

Least Response Time

応答時間が最も短いサーバーを選択する。ヘルスチェックの応答時間を計測して判断する動的なアルゴリズム。

ヘルスチェック

ロードバランサーは定期的にバックエンドサーバーの死活確認を行い、異常なサーバーへのトラフィックを自動的に遮断する。

# nginx の upstream ヘルスチェック設定例
upstream backend {
    server 192.168.1.10 max_fails=3 fail_timeout=30s;
    server 192.168.1.11 max_fails=3 fail_timeout=30s;
    server 192.168.1.12 max_fails=3 fail_timeout=30s;
}

# AWS ALBのターゲットグループ設定例
health_check:
  path: /health
  interval: 30s
  timeout: 5s
  healthy_threshold: 2    # 2回連続成功でヘルシーと判定
  unhealthy_threshold: 3  # 3回連続失敗でアンヘルシーと判定

アプリケーション側にはヘルスチェック用エンドポイントを実装する。

@app.get("/health")
def health_check():
    # DBへの接続確認など、依存サービスも確認するのがベストプラクティス
    try:
        db.execute("SELECT 1")
        return {"status": "healthy", "db": "ok"}
    except Exception:
        raise HTTPException(status_code=503, detail="DB connection failed")

SSL終端(SSL Termination)

L7ロードバランサーがSSL/TLSを処理し、バックエンドサーバーへはHTTPで通信するパターン。

クライアント ──HTTPS──→ [LB: SSL終端] ──HTTP──→ バックエンドサーバー

メリット:

  • SSL証明書の管理をLB1箇所に集約できる
  • バックエンドサーバーの暗号化処理負荷を削減
  • HTTP/2のサポートをLBで一括対応できる

SSL パススルー: LBはSSLを解読せず、バックエンドサーバーまでSSL接続を通す。バックエンド側が復号するため、LBはL4動作になる。エンドツーエンドの暗号化が必要な場合に使う。

セッション永続化(Session Persistence)

セッション情報をサーバーのメモリに保持するアーキテクチャでは、同一クライアントを常に同じサーバーへ転送する必要がある(スティッキーセッション)。

1. クライアントがリクエストを送信
2. LBがサーバーを選択し、Set-Cookieヘッダーでサーバー識別子を返す
   Set-Cookie: SERVERID=srv-A; Path=/; HttpOnly
3. 以降のリクエストでCookieをもとに同じサーバーへ転送

AWS ALBでは「Sticky Sessions」機能として提供されている。

より良い設計: 外部セッションストア

スティッキーセッションへの依存は可用性を下げる(対象サーバーがダウンするとセッションが失われる)。セッション情報をRedisなどの外部ストアに保存することで、LBはどのサーバーへ転送してもセッションを引き継げるようになる。

クライアント → LB → サーバーA: セッションIDを受け取る
サーバーA → Redis: セッション情報を保存

次のリクエスト:
クライアント → LB → サーバーB(Aとは別のサーバー)
サーバーB → Redis: セッション情報を取得 → 問題なく処理できる

グローバルロードバランシング

複数のリージョン(データセンター)をまたいだロードバランシングはDNSレベルで行う。

ユーザーが example.com を解決する
    ↓
DNS(GeoDNS)がユーザーの位置を判断
    ├── 日本ユーザー → 東京リージョンのIPを返す
    ├── 欧州ユーザー → フランクフルトリージョンのIPを返す
    └── 米国ユーザー → バージニアリージョンのIPを返す

ただしDNSのTTLがある間は切り替えに時間がかかるため、フェイルオーバーの即時性は限定的だ。Anycastルーティング(同じIPアドレスを複数拠点でアドバタイズし、BGPで最近傍へ誘導する)を使うとより高速な切り替えが可能になる。CloudflareなどはAnycastを活用している。


まとめ

ロードバランサーはL4(トランスポート層)とL7(アプリケーション層)で動作レベルが異なり、それぞれに適した用途がある。高スループットと低レイテンシが必要なネットワーク負荷分散にはL4、HTTPの詳細なルーティングやSSL終端が必要な場合はL7が適している。

分散アルゴリズムはラウンドロビン・加重ラウンドロビン・最小接続数・IPハッシュなどがあり、サーバースペックの均一性やリクエストの処理時間の分布によって選択する。セッション管理はスティッキーセッションよりRedisなどの外部ストアを使う設計の方が、スケーラビリティと可用性の観点で優れている。ロードバランサーの設計はインフラスケーリング戦略の核心であり、適切な選択と設定がサービスの安定稼働を支える。

免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。