2026年5月24日
2026年5月24日
ロードバランサーで複数IPに振り分ける構成|方式の選び方・nginx/HAProxyの設定例・WordPressでの注意点
1つの入り口(ロードバランサー)で受けたアクセスを、複数のサーバーのIPアドレスへ振り分けると、負荷を分散でき、1台が止まってもサービスを続けられます。構成を決めるときに考えることは、「どの層で振り分けるか」「どの順番で振り分けるか」「止まったサーバーをどう外すか」「元のクライアントIPをどう引き継ぐか」の4つです。この記事では、それぞれの選び方と nginx・HAProxy の設定例、WordPress を複数台で動かすときの注意点を説明します。
振り分け方式を選ぶ
複数IPへの振り分けには、大きく3つの方式があります。
- DNSラウンドロビン:1つのホスト名に複数のAレコードを登録し、名前解決の段階で分散させます。追加の機器は不要ですが、停止したサーバーのIPもしばらく返され続け、クライアントやリゾルバーのキャッシュの影響で偏りも出ます。障害時の切り離しを重視するなら、これだけに頼るのは避けます。
- L4(TCP)ロードバランサー:TCPやUDPの接続単位で振り分けます。中身を解釈しないので軽く、HTTP以外のプロトコルにも使えます。代わりに、URLごとの振り分けやHTTPヘッダーの付与はできません。
- L7(HTTP)ロードバランサー:HTTPリクエストを解釈して振り分けます。URLやホスト名による振り分け、ヘルスチェックでのステータスコード確認、
X-Forwarded-Forの付与などができます。WebサイトやWordPressなら、まずこちらを検討します。
クラウドでは、L4・L7それぞれのマネージドなロードバランサーが提供されています。ロードバランサー自体の冗長化を事業者に任せられるのが利点で、機能や設定項目はサービスごとに異なります(2026年10月現在)。
振り分けのアルゴリズム
代表的な振り分け方は次のとおりです。
- ラウンドロビン:順番に振り分けます。サーバーの性能が揃っていて、処理時間のばらつきが小さい場合に向きます。
- 重み付き:性能の高いサーバーに多く振り分けます。新しいサーバーを少しずつ投入するときにも使えます。
- 最小接続数(least connections):処理中の接続が少ないサーバーへ振り分けます。重い処理が混じるサイトに向きます。
- クライアントIPによるハッシュ:同じクライアントを同じサーバーへ送ります。サーバーにセッションを持つアプリで使いますが、オフィスなど同じIPから大量にアクセスがあると偏ります。
可能であれば、セッションをサーバーに持たない作り(後述)にして、ハッシュに頼らない構成にするほうが運用しやすくなります。
nginx で複数IPに振り分ける
nginx のオープンソース版では、upstream に複数のサーバーを並べて振り分けます。設定を変える前に既存の設定ファイルをバックアップしておきます。
upstream wp_backend {
least_conn;
server 10.0.0.11:80 max_fails=3 fail_timeout=30s;
server 10.0.0.12:80 max_fails=3 fail_timeout=30s;
server 10.0.0.13:80 backup;
keepalive 16;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://wp_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_next_upstream error timeout http_502 http_503;
}
}
max_fails と fail_timeout は、fail_timeout の時間内に指定回数失敗したサーバーを、その時間だけ振り分け対象から外す設定です。オープンソース版のこの仕組みは、実際のリクエストの失敗で判断する「受動的なヘルスチェック」で、定期的に確認用のリクエストを送る能動的なヘルスチェックは商用版の機能です。backup を付けたサーバーは、ほかのサーバーがすべて使えないときだけ使われます。なお、backup は ip_hash などハッシュ系の方式とは組み合わせられません。
proxy_next_upstream は、失敗時に次のサーバーへ再送する条件です。POST のように同じ処理を繰り返すと困るリクエストは、既定では再送されません。
設定後は sudo nginx -t で文法を確認してから sudo systemctl reload nginx で読み込み直します。
HAProxy で能動的なヘルスチェックを使う
定期的にバックエンドの状態を確かめたい場合は、HAProxy が使いやすい選択肢です。以下は HAProxy 2.2 以降の書き方の例です。
frontend fe_http
bind :80
mode http
option forwardfor
default_backend be_web
backend be_web
mode http
balance roundrobin
option httpchk
http-check send meth GET uri /healthz.html ver HTTP/1.1 hdr Host www.example.com
http-check expect status 200
server web1 10.0.0.11:80 check inter 5s fall 3 rise 2
server web2 10.0.0.12:80 check inter 5s fall 3 rise 2
server web3 10.0.0.13:80 check backup
inter 5s fall 3 rise 2 は「5秒ごとに確認し、3回続けて失敗したら外し、2回続けて成功したら戻す」という意味です。haproxy -c -f /etc/haproxy/haproxy.cfg で設定を検証してから再読み込みします。
ヘルスチェック用のURLは、何を確認したいかで選びます。静的なファイルならWebサーバーが生きているかだけを、DBに接続する軽いPHPなら、アプリが応答できるかまでを確認できます。ただし、DBが止まったときに全台が同時に外れ、すべてのリクエストがエラーになる点は理解しておいてください。
元のクライアントIPを引き継ぐ
ロードバランサーを挟むと、バックエンドから見た接続元はすべてロードバランサーのIPになります。アクセスログ、IP制限、ログイン試行の制限などが正しく動くよう、元のIPを引き継ぎます。
L7なら X-Forwarded-For ヘッダーを使い、バックエンドの nginx では realip モジュールで、信頼するロードバランサーからのヘッダーだけを採用します。
# バックエンド側 nginx の設定例
set_real_ip_from 10.0.0.5;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
set_real_ip_from には、ロードバランサーのIPだけを指定します。どこからでもヘッダーを信用すると、クライアントが偽のIPを名乗れてしまいます。L4のロードバランサーではHTTPヘッダーを付けられないため、PROXY protocol を使って接続元の情報を渡します。
WordPress を複数台で動かすときの注意点
WordPress は複数台に振り分けても動きますが、1台構成のときに意識しなかった前提がいくつか崩れます。
- HTTPSの判定:ロードバランサーでTLSを終端すると、WordPressにはHTTPで届くため、管理画面のリダイレクトが繰り返されることがあります。信頼できるロードバランサーの背後で、バックエンドへ直接アクセスできない構成に限り、
wp-config.phpに次のような判定を入れます。
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
$_SERVER['HTTPS'] = 'on';
}
- アップロードファイル:メディアをアップロードしたサーバーにしかファイルが無い状態になります。共有ストレージを使うか、S3互換ストレージへのオフロードで全台から同じファイルを参照できるようにします。
- プラグインとテーマの更新:管理画面から更新すると、そのサーバーだけが新しい版になります。デプロイの仕組みで全台に配る運用にし、
DISALLOW_FILE_MODSで管理画面からの変更を止める方法もあります。 - キャッシュとセッション:オブジェクトキャッシュは Redis などの共有サーバーにまとめます。WordPress のログイン状態はCookieで管理されるので、通常はサーバー固定は不要ですが、PHPセッションを使うプラグインがある場合は確認します。
- WP-Cron:アクセスのたびに各サーバーで実行されうるため、
DISABLE_WP_CRONを設定し、1台だけからシステムのcronで実行する方法がよく使われます。
本番に入れる前に、ステージング環境で1台ずつ止めてもサイトが動くか、ログイン・投稿・画像アップロードが問題なくできるかを確かめてください。
ロードバランサー自体を単一障害点にしない
自前のロードバランサーが1台だけだと、そこが止まればすべて止まります。2台を用意して keepalived(VRRP)で仮想IPを持ち回る構成や、マネージドなロードバランサーの利用を検討します。
まとめ
- 振り分けはDNSラウンドロビン・L4・L7の3方式があり、Webサイトなら障害時の切り離しができるL7がまず候補になる
- アルゴリズムはサーバーの性能差と処理のばらつきで選び、可能ならサーバーにセッションを持たない構成にする
- nginx のオープンソース版は受動的なヘルスチェック、HAProxy は能動的なヘルスチェックが使える
- 元のクライアントIPは、信頼するロードバランサーからのヘッダーだけを採用して引き継ぐ
- WordPress ではHTTPS判定、メディアの共有、更新の配布、キャッシュ、WP-Cron を複数台向けに整える