2026年6月28日

2026年6月28日

GSLB と ヘルスチェック型DNS を組み合わせる構成例|2拠点の WordPress を振り分け、障害拠点を DNS から外す

GSLB(広域負荷分散)とヘルスチェック型DNS を組み合わせると、複数の拠点に置いたサイトのうち、応答できる拠点のアドレスだけを DNS で返せます。この記事では、2つのリージョンに WordPress を置く構成を例に、拠点内のロードバランサーと DNS 層の役割分担、WordPress に置くヘルスチェック用エンドポイント、切り替わりにかかる時間の見積もり、データベースの扱い、切り戻しと試験の方法までを具体的に説明します。DNS サービスは Amazon Route 53 を例にしますが、考え方は他の GSLB 製品でも共通です。

構成の全体像

ここで扱う構成は次のとおりです。

                       利用者
                         │ DNS 問い合わせ
                ┌────────┴────────┐
                │ GSLB(DNS 層)   │  ヘルスチェックの結果で返す IP を決める
                └───┬─────────┬───┘
         正常なら返す│         │主が異常なら返す
        ┌───────────┴──┐  ┌───┴──────────┐
        │ 拠点A(主)    │  │ 拠点B(副)    │
        │ LB → WP×2     │  │ LB → WP×2     │
        │ DB(書き込み) │─→│ DB(複製)     │
        └──────────────┘  └──────────────┘

役割は二段に分かれます。拠点の中では、ロードバランサー(ALB や HAProxy など)が個々の WordPress サーバーの死活を見て振り分けます。GSLB は拠点の単位で「この拠点の入口を返してよいか」を判断します。サーバー1台の故障は拠点内のロードバランサーが吸収し、拠点全体の障害やネットワークの断絶を GSLB が受け持つ、という分担にすると、DNS の切り替えが頻繁に起きずに済みます。

GSLB の実現方法は、Route 53 のようなマネージド DNS のヘルスチェック機能のほか、Cloudflare の Load Balancing、Azure Traffic Manager、F5 BIG-IP DNS のような専用の製品があります。名称や機能の範囲は製品ごとに異なり、変わることもあるため、選ぶときは各社の最新の説明を確認してください(2026年10月現在)。

アクティブ/スタンバイかアクティブ/アクティブか

WordPress で最初に決めるのは、両方の拠点に同時にアクセスを流すかどうかです。

WordPress は投稿、コメント、ログイン、注文などで常にデータベースへ書き込みます。2つの拠点が別々のデータベースに書き込むと内容が食い違うため、書き込み先は一か所にするのが基本です。そこでこの記事では、平常時はすべて拠点Aに向け、拠点Aが異常のときだけ拠点Bを返す「アクティブ/スタンバイ」を構成例にします。Route 53 では「フェイルオーバー」のルーティングポリシーで、主と副のレコードを作ります。

両方の拠点に流す「アクティブ/アクティブ」(Route 53 ならレイテンシーや位置情報のルーティングにヘルスチェックを付ける形)は、閲覧中心でキャッシュの効くサイトや、書き込みを一方の拠点のデータベースに集約できる構成で検討します。複製の遅れで「保存した直後に古い内容が見える」問題が起きやすいため、ログインや管理画面の扱いまで含めて設計が必要です。

WordPress にヘルスチェック用のエンドポイントを置く

ヘルスチェックの対象をトップページにすると、キャッシュが返っているだけでデータベースが止まっている状態を見逃すことがあります。データベースへの問い合わせまで確かめる軽いエンドポイントを、mu-plugin として用意する例です。wp-content/mu-plugins/healthz.php に置きます。作業はステージングで試してから本番に入れてください。

<?php
/**
 * Plugin Name: Health Check Endpoint
 * Description: GSLB のヘルスチェック用に、DB への接続を確かめる軽いエンドポイントを提供する(例)
 */

defined( 'ABSPATH' ) || exit;

add_action( 'rest_api_init', function () {
	register_rest_route(
		'healthz/v1',
		'/status',
		array(
			'methods'             => 'GET',
			'callback'            => 'myhc_status',
			// 返すのは ok / ng だけで、内部の情報は出さないため認証は求めない
			'permission_callback' => '__return_true',
		)
	);
} );

function myhc_status() {
	global $wpdb;

	$ok = ( '1' === (string) $wpdb->get_var( 'SELECT 1' ) );

	// 保守作業のときに拠点を手動で外すためのファイル(任意)
	if ( file_exists( WP_CONTENT_DIR . '/healthz-drain' ) ) {
		$ok = false;
	}

	$response = new WP_REST_Response(
		array( 'status' => $ok ? 'ok' : 'ng' ),
		$ok ? 200 : 503
	);
	$response->header( 'Cache-Control', 'no-store' );

	return $response;
}

URL は https://www.example.com/wp-json/healthz/v1/status になります。データベースに接続できない場合は、このコードに届く前に WordPress がエラー画面を返しますが、その場合も応答は 200 以外になるため、ヘルスチェックは失敗と判断します。

healthz-drain というファイルを置くと、データベースが正常でも 503 を返します。拠点Aを保守するときに、このファイルを作れば GSLB から外れ、消せば戻ります。DNS の設定画面を触らずに切り替えられるので、作業手順が単純になります。

このエンドポイントでは、次の点に注意します。

  • キャッシュさせない:Cache-Control: no-store を付けています。CDN を経由させると CDN の応答を見てしまうので、ヘルスチェックは拠点のロードバランサーに直接向けます。
  • 遮断させない:REST API を制限するプラグインや WAF が、ヘルスチェックの送信元を弾いていないか確認します。Route 53 のヘルスチェックの送信元アドレスの範囲は AWS が公開しています。
  • 重くしない:外部 API への接続など、遅い処理は入れません。ヘルスチェック自体が負荷や誤判定の原因になります。

Route 53 でヘルスチェックとフェイルオーバーを設定する

ヘルスチェックは拠点ごとに作ります。対象は拠点Aのロードバランサーのアドレスまたはホスト名、プロトコルは HTTPS、パスは上のエンドポイント、ホスト名には www.example.com を指定して、WordPress が正しいサイトとして応答するようにします。応答本文に "status":"ok" が含まれるかを見る文字列一致の設定を使うと、別のページが 200 で返ってくる誤判定を避けられます。

レコードはフェイルオーバーのポリシーで2行作ります。

{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "site-a-primary",
        "Failover": "PRIMARY",
        "TTL": 60,
        "ResourceRecords": [ { "Value": "192.0.2.10" } ],
        "HealthCheckId": "your-health-check-id-for-site-a"
      }
    },
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "site-b-secondary",
        "Failover": "SECONDARY",
        "TTL": 60,
        "ResourceRecords": [ { "Value": "198.51.100.20" } ],
        "HealthCheckId": "your-health-check-id-for-site-b"
      }
    }
  ]
}

ロードバランサーが AWS の ALB の場合は、IP アドレスの代わりにエイリアスレコードを使うのが一般的です。その場合はエイリアスの「ターゲットのヘルスを評価」の設定と、独自のヘルスチェックのどちらで判断するかを決めておきます。拠点のロードバランサーの状態とデータベースの状態を両方見たいときは、複数のヘルスチェックをまとめる「算出されたヘルスチェック」も使えます。画面の名称は変わることがあるので、AWS のドキュメントで確認してください。

作業の前には、aws route53 list-resource-record-sets で現在のレコードを書き出して保存しておきます。

切り替わりにかかる時間を見積もる

「拠点Aが止まってから、利用者が拠点Bに着くまで」の時間は、おおよそ次の足し算になります。

  • ヘルスチェックが異常と判断するまで:確認の間隔 × 失敗とみなす回数(例: 30秒 × 3回 = 約90秒)
  • DNS のキャッシュが切れるまで:レコードの TTL(例: 60秒)
  • 利用者側の事情:TTL を守らないリゾルバーや、ブラウザが同じ接続を使い続ける時間

この例では数分程度を見込むことになります。間隔を短くし、TTL を下げれば早くなりますが、問い合わせの量やヘルスチェックの条件が変わり、一時的な遅延で切り替わる誤判定も起きやすくなります。サイトの性質に合わせて、どこまで待てるかを先に決めてから値を選んでください。

データベースの切り替えは別に考える

DNS が拠点Bを返すようになっても、それだけでは拠点Bのデータベースは書き込み可能になりません。ここを見落とすと、切り替わった先で「表示はできるがログインも投稿もできない」状態になります。選択肢は主に三つです。

  1. 副拠点は閲覧専用で受ける:拠点Bのデータベースは複製のまま、コメントや投稿を一時的に止める。WordPress 側で書き込み操作を受け付けない保守用の設定を用意しておきます。
  2. データベースの昇格を手順化する:拠点Bの複製を書き込み可能にする手順を用意し、障害時に人が判断して実行します。マネージドデータベースの切り替え機能を使う場合は、その製品の説明に沿って試験しておきます。
  3. 副拠点は静的なお知らせページ:拠点Bにはサイトを置かず、障害のお知らせだけを返す。構成は最も単純です。

自動でデータベースまで切り替える設計は、ネットワークの分断で両方の拠点が「自分が主」と判断する危険があります。まずは手動の判断を挟む形から始めるほうが安全です。

切り戻しと試験

Route 53 のフェイルオーバーは、拠点Aのヘルスチェックが正常に戻ると、自動で拠点Aを返すようになります。データベースを拠点Bに昇格させていた場合、そのまま戻ると書き込み先が食い違います。昇格を伴う切り替えをした後は、拠点Aに healthz-drain を置いて外したままにし、データの整理が済んでから消して戻す、という手順にしておくと事故を防げます。

本番に入れる前に、次の試験を行います。

  • 拠点Aに healthz-drain を置き、ヘルスチェックが異常になって拠点Bが返るまでの時間を測る
  • dig www.example.com +short を権威サーバーと公開リゾルバーの両方に対して繰り返し実行し、応答の変化を見る
  • ファイルを消して、拠点Aに戻ることを確かめる
  • 切り替え中の管理画面の動作、ログインの状態、キャッシュの影響を確認する

まとめ

  • 拠点内のサーバー故障はロードバランサー、拠点全体の障害は GSLB と、二段に役割を分けると切り替えが安定します。
  • WordPress は書き込み先を一か所にする必要があるため、まずはアクティブ/スタンバイ(フェイルオーバー)の構成が扱いやすいです。
  • ヘルスチェックはデータベースまで確かめる軽いエンドポイントを mu-plugin で用意し、キャッシュと遮断を避けます。手動で外すための仕組みもあると便利です。
  • 切り替え時間は「間隔 × 回数 + TTL + 利用者側の事情」で見積もり、データベースの昇格と切り戻しの手順を別に用意して、試験してから本番に入れます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲