設定を読む前に:TLS終端・Hostと転送ヘッダーの信頼・障害時の継続は別々に確認します。旧コードは比較用に保持し、直前の訂正と新しい隔離例を区別しています。
| この記事の要点 |
|
概要
ロードバランサ (load balancer / 負荷分散装置) とは、クライアントからの要求を複数のサーバへ振り分ける装置・ソフトウェアです。1 台のサーバに処理が集中するのを防ぎ、全体の処理能力 (スケーラビリティ) と、障害時にも継続できる可能性を高めますが、停止しない保証ではありません。Web サイトへのアクセスが増えても、共有DB・回線・セッション等の制約も確認して処理能力を増やす「スケールアウト」の要となる仕組みです。親項目の 負荷分散・プロキシ・CDN を参照してください。
実体は リバースプロキシ と重なる部分が多く、nginx や HAProxy はリバースプロキシでありロードバランサでもあります。クラウドでは NLB (Network Load Balancer) や ALB (Application Load Balancer) としてマネージドサービスが提供されています。
仕組み
ロードバランサは、どの層 (レイヤ) の情報を見て振り分けるかで大きく 2 種類に分かれます。OSI 参照モデルの第 4 層か第 7 層かが分類の軸です。
- L4 ロードバランサ (NLB): トランスポート層 (TCP/UDP) の情報、すなわち IPアドレス・ポート・プロトコル等のフロー情報で振り分ける。HTTP以外にも使えるが、対応プロトコルと性能は実装・構成による。NLB/ALBはクラウド製品名にも使われ、L4/L7の完全な同義語ではない。
- L7 ロードバランサ (ALB): アプリケーション層まで見て、HTTP のパス・ホスト名・Cookie・ヘッダの内容に応じて振り分ける。
/apiはアプリ群、/imgは静的配信群、といった賢いルーティングができる。SSL 終端もここで行うことが多い。
振り分け方 (分散アルゴリズム) には次のようなものがあります。
- ラウンドロビン: サーバを順番に 1 台ずつ均等に回す。最も基本的でシンプル。
- 最小接続 (least connections): その時点で接続数が最も少ないサーバへ送る。処理時間にばらつきがある場合に有効。
- IP ハッシュ: クライアント IP のハッシュ値で送り先を決める。同じIPは通常同じ送り先になりやすいが、候補の変更や障害時には変わる。NAT配下の偏りやIP変更にも注意し、セッション永続化とは分ける。
- 重み付け (weighted): 性能の高いサーバに多めの重みを与え、能力に応じて配分する。
さらに、実要求の失敗を使う受動監視と、定期的な確認要求を送る能動監視のヘルスチェックと、同じ利用者を同じサーバへ固定するセッション維持 (スティッキーセッション) が重要な要素です。
設定・実用例
nginx の upstream を使った L7 ロードバランサの例です。3 台のバックエンドへ最小接続方式で分散し、重み付けと受動的な失敗回数の条件を指定しています。定期的な能動監視ではありません。
保存した旧例への注意:旧upstream例の訂正:max_fails=3 / fail_timeout=30s は実要求で失敗を観測する受動監視で、30秒ごとの/healthz送信ではありません。指定のない2台は既定値max_fails=1 / fail_timeout=10sです。HTTP平文・Host/転送ヘッダー信頼は未完成で、ip_hashに替えると同じ接続分散にはなりません。
upstream app_backend {
least_conn; # 最小接続方式
server 10.0.0.11:3000 weight=3; # 高性能機に多めの重み
server 10.0.0.12:3000 weight=1;
server 10.0.0.13:3000 weight=1 max_fails=3 fail_timeout=30s;
# IP ハッシュで固定したい場合は least_conn の代わりに:
# ip_hash;
}
server {
listen 80;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
各サーバの生死は、外形監視として定期的に確認できます。
保存した旧例への注意:旧curl例の訂正:これは人が1回ずつ確認する読取例で、nginxの候補を自動除外しません。-sは診断エラーも隠し、時間上限もありません。HTTP 200だけで依存DB・書込処理・余力の正常性は証明できません。対象の許可とタイムアウトを決め、外形監視とLB制御を混同しないでください。
# 各バックエンドのヘルスチェック用エンドポイントを叩く例
curl -s -o /dev/null -w "%{http_code}\n" http://10.0.0.11:3000/healthz
curl -s -o /dev/null -w "%{http_code}\n" http://10.0.0.12:3000/healthz
主な用途
- スケールアウト: アクセス増に対しサーバを横に並べ、ロードバランサで分散して処理能力を上げる。
- 高可用性: 残存サーバへ切り替える設計。検知前・処理途中の要求、入口やDBの障害、残存容量不足は別途対策する。
- 無停止メンテナンス: 新規要求の振分け停止、既存接続のdrain、処理完了確認、更新と復帰確認を順に設計する。ヘルスチェック停止だけではdrainや無停止を保証しない。
- SSL 終端: L7 LB で HTTPS を一括復号し、バックエンドを単純化する。
- 地理/用途別振り分け: パスやホスト名でマイクロサービス群へ振り分ける。
L4 と L7 の比較
| 観点 | L4 ロードバランサ (NLB) | L7 ロードバランサ (ALB) |
|---|---|---|
| 見る情報 | IP アドレス + ポート | HTTP パス・ヘッダ・Cookie |
| 速度 | 実装・暗号処理・負荷に依存 | ルール・接続・処理内容に依存。層だけで順位は決まらない |
| 対応プロトコル | TCP/UDP 全般 | 主に HTTP/HTTPS |
| 賢いルーティング | 不可 (中身を見ない) | 可 (パス/ホスト別) |
| SSL 終端 | TCP透過中継のほかTLS終端機能を持つ製品もある | HTTPSを内容解析する場合は復号する構成を確認 |
注意点
- ロードバランサ自体の冗長化: LB が単一障害点になると本末転倒。LB 自体も冗長構成 (アクティブ/スタンバイ等) にする。
- セッション維持の落とし穴: スティッキーセッションで特定サーバに固定すると、そのサーバ停止時にセッションが失われる。セッションを外部 (Redis 等) に持たせる設計が望ましい。
- ヘルスチェックの設計: チェックが甘いと故障機に送り続け、厳しすぎると正常機を切り離す。エンドポイントと閾値を適切に決める。
- 偏り: ラウンドロビンでも処理時間がばらつくと負荷が偏る。最小接続や重み付けを検討する。
- クライアント IP の保持: L7 LB ではバックエンドから見た送信元が LB の IP になるため、
X-Forwarded-Forで元 IP を引き継ぐ。
受動監視と再送を区別して試す
次はHTTPのloopback隔離例です。第1候補が接続できない、応答ヘッダー前にtimeout、または503なら、条件の範囲でbackupへ試行します。max_fails=1 / fail_timeout=3sは3秒間の失敗観測と除外期間で、定期監視の周期ではありません。1台だけのupstreamではmax_fails / fail_timeoutは無視されます。共有zoneがない場合の状態はworkerごとです。
# http context; HTTP loopback lab only. No periodic health probes.
upstream lab_pool {
least_conn;
server 127.0.0.1:18083 max_fails=1 fail_timeout=3s;
server 127.0.0.1:18084 backup;
}
server {
listen 127.0.0.1:18085 default_server;
server_name _;
return 400;
}
server {
listen 127.0.0.1:18085;
server_name app.example.test;
location / {
proxy_pass http://lab_pool;
proxy_set_header Host app.example.test;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Forwarded "";
proxy_connect_timeout 1s;
proxy_read_timeout 2s;
proxy_next_upstream error timeout http_503;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 3s;
}
}
tries=2は初回を含む試行数の上限、next_upstream_timeoutは次候補へ渡せる時間の制約で、要求全体の完了期限ではありません。既にクライアントへ応答を送った後の失敗は、別サーバで継ぎ足して直せません。503を失敗として数えるかはproxy_next_upstream等の条件にも依存します。
更新要求は重複実行を前提に設計します。nginxは通常、上流へ送信済みのPOST / LOCK / PATCHを再送しませんが、non_idempotentを追加すると許可します。GETだから業務上副作用がない保証もありません。アプリやクライアントの再試行を含めて冪等キー・結果照会・重複排除を設計し、決済などのlocationではproxy_next_upstream offを選ぶことも検討します。offでもクライアントの二重送信は防げません。
OSSの監視とNGINX Plus
標準NGINX Open Sourceのmax_failsは実要求に基づく受動監視です。定期HTTPプローブを行うhealth_check moduleはNGINX Plusの商用機能です。外部監視からcurlを送っただけではupstreamの候補は自動で切り離されません。導入版・module・連携方法を確認します。
停止を避けるための運用判断
入口LBが1台、共有DBが1系統、セッションやアップロードが各サーバのローカルにしかない場合、バックエンドの増設だけでは継続できません。故障検知時間、残った処理能力、接続drain、セッション移行と業務処理の完了を観測します。stickyはデータの複製でも冗長化でもありません。TLS終端後の平文区間と転送ヘッダーの信頼は、リバースプロキシ設定と同様に別途設計します。
公式資料と検証範囲
2026年10月26日確認:nginxの転送・URI・ヘッダー・TLS検証・タイムアウトと再送、upstreamの失敗判定とbackup、受動/能動監視、商用health_check module、Hostとdefault server、信頼する中継元、reloadとworker交代、ApacheのHost保持。
新しいHTTP例はPC上の外部ネットワークなし・loopbackの専用nginxで検査するためのものです。公開TLS・実CDN・Apache・NGINX Plus・実アプリの認証や本番の無停止性は検証対象外です。設定・証明書・導入版・module・到達制限が異なる環境へ、試験結果をそのまま適用しないでください。
関連リンク
子ページはありません
- フォワードプロキシ
- リバースプロキシ
- ロードバランサ
- nginxリバースプロキシ設定
- HAProxy
- CDN
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Django REST FrameworkでAPIを作る|URL接続・入力検証・所有者の認可 2026-10-25 21:03:21
- DjangoモデルをJSONで返す|型・公開フィールド・DRF認可 2026-10-25 20:46:35
- precompile standard library とは(Pythonインストール) 2026-10-25 20:30:17
- ANACONDA NAVIGATORの起動方法 2026-10-25 20:30:17
- DjangoのAjax POST|CSRF・JSON入力検証・DRFの認可 2026-10-25 20:30:16
- Django/MySQLのUnknown column ...id|主キー・実列・別名の確認 2026-10-25 20:08:53
- 【django】limit, offsetの指定方法 2026-10-25 20:08:51
- Djangoの本番で変更が反映されないとき|プロセス・テンプレート・静的配信の確認 2026-10-25 19:40:35
- Django のファイルアップロード|ファイル名と拡張子の取得 2026-10-25 19:40:35
- djangoにおけるHTTPステータスコードの返し方 2026-10-25 19:40:34
- PythonのResponseオブジェクトの中身の確認 2026-10-25 19:17:54
- Python で Cookie を扱う|requests の Session と http.cookies 2026-10-25 19:17:54
- Python で HTTP リクエスト|requests・urllib・httpx と curl の対応 2026-10-25 19:17:53
- Django で SQL ログを出力する方法|django.db.backends と N+1 の発見 2026-10-25 18:59:32
- djangoにおけるログのローテート設定【Python】 2026-10-25 18:59:31