Microsoft CDNで静的サイトが一部504になる原因と対処|Azure Storage×Front DoorでのGateway Timeout完全ガイド

Azure Storage の静的ウェブサイトをオリジンにし、Microsoft CDN(現行の Azure Front Door Standard/Premium ベース)で配信していると、ピーク外でも数分だけ一部リソースが 504 Gateway Timeout を返して自然復旧する──そんな「つかみどころのない」事象に悩まされることがあります。本稿では、2025年の海底ケーブル断線に伴う広域ネットワーク収束の影響を含め、原因の芯を言語化し、Azure ポータル/ログ/KQL/クライアント検証を使った再現性ある確認・対処手順と再発抑止の設計を、実務目線の HTML 記事でまとめます。

目次

想定構成と現象の整理

項目内容
オリジンAzure Storage(静的ウェブサイト機能)
CDNMicrosoft CDN(カスタムドメイン)
※実体は Azure Front Door Standard/Premium 相当のプラットフォームに統合
リージョン西ヨーロッパ/カナダ中部/オーストラリア東部
現象ピーク外に数分間だけ一部オブジェクトが 504。のち自動復旧。
ファイアウォール・ネットワークルール・設定変更なし。他エラー顕著でなし。
確認したいこと原因の芯/確認・対処の具体的手順/再発抑止の設計

結論(要点だけ先に)

  • 504 は「CDN エッジからオリジンへ送ったリクエストが既定時間内に応答しなかった」ときに発生します。Azure Front Door の既定タイムアウトは 30 秒で、16–240 秒の間で調整可能です。
  • 複数リージョンで同時かつ短時間に発生・自然復旧というパターンは、構成ミスやアプリではなく広域ネットワークの一時的障害(経路切替・収束)で説明しやすいケースです。
  • 2025 年 9 月初旬、紅海の海底ケーブル複数系で断が発生し、Microsoft Azure を含むグローバル経路で中東経由トラフィックの遅延上昇が告知されました。こうした事象の波及で、一時的に CDN→オリジン間の TTFB が伸び、ErrorInfo: OriginTimeout を伴う 504/ログ上 0 ステータスが短時間出ることがあります。
  • まずは Azure Status/Service Health、Storage メトリクス、Front Door アクセスログの三点で「基盤要因か/自サービス要因か」を切り分け、基盤要因であれば経路再収束を待ちつつ監視、自サービス要因ならオリジン性能・タイムアウト・キャッシュ/ルールの整備で対処します。

なぜ CDN で 504 が起きるのか(仕組み)

Azure Front Door(Microsoft CDN 基盤)では、クライアント→エッジ間と、エッジ→オリジン間は別セッションです。エッジはキャッシュミス時にオリジンへ取りに行きますが、オリジンが応答を返し始めるまでの時間や、完了までの時間が構成された上限を超えると、エッジは処理を中止してクライアントに 503/504 系を返します。アクセスログでは次の点が重要です。

  • TimetoFirstByte(エッジが最初のバイトをクライアントへ返すまで)と TimeTaken(最終バイトまで)。
  • HttpStatusCode と ErrorInfo。オリジンの応答タイムアウト時はログ上 HttpStatusCode=0 で ErrorInfo=OriginTimeout になる仕様に注意(クライアント側では 504 と見える)。
  • CacheStatus(HIT/MISS/REMOTE_HIT/…)と OriginURL/OriginName、Pop(応答したエッジ PoP)。

今回のパターンで主因となりやすいもの

「ピーク外・数分限定・複数リージョン同時・その後自然復旧」という形は、個別のアプリや設定では説明しづらく、広域ネットワーク側の迂回・再収束で生じる一過性の遅延上振れ(ジッタ)と整合します。実際、2025 年 9 月 6 日(UTC)前後に紅海の複数海底ケーブルで切断が発生し、Microsoft を含むクラウド事業者が中東経路の遅延上昇と迂回を告知しています。こうしたイベントは、欧州↔アジア/豪州、北米↔欧州など広域の経路に波及し、TTFB/TTL の伸長や瞬間的な 504 を誘発し得ます。

まずやるべき確認・対処(実務フロー)

手順やること狙いコツ/判断ポイント
① 基盤ステータス確認Azure Status(azure.status.microsoft)とサブスクリプションの Service Health を確認(Networking/Storage のアドバイザリ・インシデント)。広域/基盤側のイベント有無を即時把握。「中東経路」「海底ケーブル」「迂回」「Latency 増」等のワードが出ていれば基盤要因濃厚。
② Storage メトリクスポータル→モニター > メトリクスでSuccessE2ELatency、SuccessServerLatency、Availability、Transactions を 1 分粒度で可視化。オリジン自体の処理遅延/エラー有無を把握。E2E − ServerLatency が膨らんでいればネットワーク/クライアント起因が示唆される。
③ Front Door ログCDN/Front Door プロファイルで アクセスログ を Log Analytics へ出力。ErrorInfo・TimetoFirstByte・TimeTaken・CacheStatus を分析。タイムアウトの発生点(エッジ?オリジン?)と影響範囲(特定 PoP?)を特定。ログ上は 504 でなく HttpStatusCode=0 のOriginTimeoutとして記録される点に注意。
④ ユーザー側キャッシュ整合障害収束でも特定オブジェクトだけ 504/破損ならキャッシュパージ(Purge)。エッジ/親キャッシュの不整合解消。大規模 Purge はコスト/負荷増。パスやタグを絞る。
⑤ クライアント経路更新利用者へ DNS キャッシュクリアを案内:
ipconfig /flushdns(Windows)
sudo killall -HUP mDNSResponder(macOS)
新しいルート/迂回が適用されやすくなる。ISP のリカーシブ DNS に依存。完璧ではないが副作用は小。
⑥ 待機と自動復旧海底ケーブル断等の広域障害は 15–60 分程度で経路再収束することが多い。無用な再デプロイ・設定変更を避ける。収束までリトライ+指数バックオフを推奨。
⑦ サポート連携失敗時の X-Azure-Ref(追跡 ID)と x-ms-request-id(Storage 側)・Front Door ログを添付してケース起票。広域イベントと自テナント事象の相関を迅速化。再現時間(UTC)、影響 URL、PoP、クライアント ASN/地域を添えると速い。

ログ/KQL での実践的な見方(テンプレ付)

Front Door(Microsoft CDN 基盤)のアクセスログは Log Analytics の AzureDiagnostics に取り込まれます(カテゴリ FrontdoorAccessLog。環境により ResourceProvider が MICROSOFT.NETWORK もしくは MICROSOFT.CDN)。以下の KQL はフィールド名の揺れに配慮しつつ、短時間の 504/OriginTimeout バーストを炙り出すサンプルです。

// 直近 24 時間、Origin タイムアウト相当の要求を抽出(環境差に強い書き方)
let T = 24h;
AzureDiagnostics
| where TimeGenerated > ago(T)
| where Category == "FrontdoorAccessLog"
| extend http = toint(column_ifexists("HttpStatusCode_d", 0))
| extend err = tostring(column_ifexists("ErrorInfo_s", ""))
| extend ttfb = todouble(column_ifexists("TimetoFirstByte_d", real(null)))
| extend taken = todouble(column_ifexists("TimeTaken_d", real(null)))
| extend pop = tostring(column_ifexists("Pop_s",""))
| extend origin = tostring(column_ifexists("OriginName_s",""))
| extend cache = tostring(column_ifexists("CacheStatus_s",""))
// 仕様上、オリジン応答タイムアウトは HttpStatusCode=0 かつ ErrorInfo=OriginTimeout になる
| where http == 504 or (http == 0 and err =~ "OriginTimeout")
| summarize Count = count(), AvgTTFB = avg(ttfb), AvgTimeTaken = avg(taken) by bin(TimeGenerated, 5m), pop, origin
| order by TimeGenerated desc
// 特定時間帯の PoP ごとの傾向(CacheStatus も参照)
AzureDiagnostics
| where TimeGenerated between (datetime(2025-09-06T05:30:00Z) .. datetime(2025-09-06T07:30:00Z))
| where Category == "FrontdoorAccessLog"
| extend pop = tostring(column_ifexists("Pop_s",""))
| extend cache = tostring(column_ifexists("CacheStatus_s",""))
| extend err  = tostring(column_ifexists("ErrorInfo_s",""))
| summarize Total=count(), OriginTimeout=countif(err == "OriginTimeout"),
          Hit=countif(cache in ("HIT","REMOTE_HIT","PARTIAL_HIT")),
          Miss=countif(cache == "MISS")
  by pop
| order by OriginTimeout desc
// 追跡 ID(X-Azure-Ref)でピンポイント追跡
let track = "(ユーザーのエラー画面に出た X-Azure-Ref の値を貼る)";
AzureDiagnostics
| where Category == "FrontdoorAccessLog"
| where tostring(column_ifexists("TrackingReference_s","")) == track
| project TimeGenerated, HttpStatus=tostring(column_ifexists("HttpStatusCode_d","")),
          ErrorInfo=tostring(column_ifexists("ErrorInfo_s","")),
          RequestUri=tostring(column_ifexists("RequestUri_s","")),
          OriginURL=tostring(column_ifexists("OriginUrl_s","")), TimetoFirstByte=todouble(column_ifexists("TimetoFirstByte_d", real(null))),
          TimeTaken=todouble(column_ifexists("TimeTaken_d", real(null))), Pop=tostring(column_ifexists("Pop_s","")),
          CacheStatus=tostring(column_ifexists("CacheStatus_s",""))

併せて Storage 側ログ(StorageBlobLogs)で同時刻帯の SuccessE2ELatency と SuccessServerLatency を可視化すると、「オリジンは速いが道中で遅い」のか「オリジン自体が遅い」のかが分かります。

// Storage のレイテンシメトリクス(1 分粒度)
AzureMetrics
| where TimeGenerated > ago(24h)
| where ResourceProvider == "MICROSOFT.STORAGE"
| where MetricName in ("SuccessE2ELatency", "SuccessServerLatency", "Availability")
| summarize Avg = avg(Val) by MetricName, bin(TimeGenerated, 1m), ResourceId
| order by TimeGenerated desc

クライアントでの簡易切り分け

ユーザー報告を受けたら、まずは該当ファイルのヘッダーを採取し X-Azure-Ref を得ます。合わせて TTFB を取り、直近の PoP/迂回状況も確認します。

# ヘッダーと計測(Windows/macOS/Linux 共通)
curl -I -w "TTFB: %{time_starttransfer}s\nTOTAL: %{time_total}s\n" https://www.example.com/path/to/file.css

# 迂回経路と DNS 解像の確認
nslookup www.example.com
traceroute(macOS/Linux) / tracert(Windows) www.example.com

TTFB が 30 秒付近で頭打ち → 504 になるなら、Front Door 既定タイムアウト(30 秒)に達している可能性が高く、Origin Response Timeout を適切に引き上げる(最大 240 秒)ことで緩和できます。ただし、グローバル障害が原因のときは引き上げが効果薄な場合があり、再収束までの再試行/待機戦略の方が有効です。

対処の優先順位(基盤要因 vs 自サービス要因)

基盤要因(海底ケーブル・広域ネットワーク障害)のとき

  • 即時:状況掲示(ステータスページ/社内連絡)。ユーザーには数十分内の自動復旧見込みとリトライを案内。
  • 監視:対象期間の OriginTimeout・PoP 分布・リージョン相関をダッシュボード化。
  • 暫定:配信に影響するクリティカルオブジェクトの事前ウォーム(プリフェッチ)や TTL 延長でキャッシュヒット率を底上げ。

自サービス要因のとき

  • オリジン遅延:ストレージ垂直/水平分割(ホットオブジェクト分離)、圧縮/最適化(画像 WebP/AVIF 化、JS/CSS minify)。
  • タイムアウト不整合:Front Door の Origin Response Timeout(16–240 秒)をワークロードに合わせて調整。
  • キャッシュ戦略:Cache-Control とルールエンジンで静的ファイルの長期キャッシュ+バージョン付け。
  • 健康監視:軽量 /_healthcheck を用意し、応答 200/TTFB しきい値でアラート。

再発防止の設計パターン(影響を最小化)

マルチオリジン(クロスリージョン)

Front Door の オリジングループで、西ヨーロッパ/カナダ中部/オーストラリア東部の Storage を束ね、優先順位+ヘルスプローブでフェイルオーバー。静的サイトはビルド成果物を各リージョンへ同報し、URL は単一(カスタムドメイン)を維持します。

  • 利点:特定地域の障害・高遅延を回避。
  • 注意:整合性(同一ビルドの配備完了確認)・署名 URL(SAS)の期限/スコープ管理。

Origin Timeout のチューニング

Front Door 既定は 30 秒です。初回フェッチ(コールド)や大きいアセット(マップ・動画字幕等)が混在する場合は 60–120 秒程度を起点に検証し、観測された 95–99 パーセンタイルの TTFB を超えるように調整します。むやみに 240 秒へ張り付けると、障害時のユーザー待ち時間が延びるため、障害検知(アラート)とセットで最適化します。

キャッシュの地理的カバレッジ/プリロード

  • リリース直後にアクセスが集中するアセットは、リージョン代表の PoP から プレウォーム(スクリプト等で GET)。
  • immutable と max-age を使い、ヒット率を KPI化(例:> 90%)。

マルチ CDN / ISP 分散

Anycast ベースのマルチ CDN(Front Door+他社 CDN)や、DNS レベルの地理/健全性ベースルーティングで、特定事業者/経路の断面影響を抑えます。ダウンタイム耐性が事業要件に含まれるなら、Active-Active 配信(同一オリジンを複数 CDN から配信・同一キャッシュキー戦略)を設計に入れます。

運用時のチェックシート(抜粋)

  • Front Door 診断ログ(アクセス/ヘルス/WAF) → Log Analytics 出力が常時有効か。
  • Storage の SuccessE2ELatency/SuccessServerLatency/Availability をダッシュボード化(1 分粒度)。
  • 重大アセットの Cache-Control と バージョニング規約(app.x.y.z.js 等)をドキュメント化。
  • 障害報告テンプレに X-Azure-Ref と x-ms-request-id、影響 URL、PoP、UTC 時刻を必須項目として運用。

FAQ:よくある疑問に短答

Q. アクセスログに 504 が見当たらないのはなぜ? A. オリジン応答タイムアウトは HttpStatusCode=0 かつ ErrorInfo=OriginTimeout で記録されます(クライアントは 504 を受け取る)。 Q. どのフィールドを見れば「遅さの所在」が分かる? A. TimetoFirstByte と TimeTaken の推移、Storage の SuccessServerLatency との差(E2E − Server)。差が大きければ経路側の可能性が高い。 Q. タイムアウト値はどこで変えられる? A. Front Door プロファイルの「Origin response timeout」。16–240 秒の範囲。既定は 30 秒。 Q. 海底ケーブル障害のとき、こちらでできる最短の手当ては? A. アナウンス確認→ユーザーへ案内→キャッシュヒット率を維持(パージしない・TTL を活かす)→監視で収束判定。無理な構成変更は逆効果になりがち。

実運用テンプレ(貼って使える)

障害報告(社内/お客様向け)

【状況】一部静的リソースで 504(数分)。現在は復旧済み/減衰中。
【対象】<ドメイン>/<パス>(例:/assets/app-*.js)
【時間(UTC)】2025-09-06 05:50〜06:07(最大)
【影響範囲】西欧・カナダ中部・豪東の利用者で散発
【原因推定】広域ネットワーク経路の迂回・再収束に伴う TTFB 上昇(海底ケーブル断の波及)
【技術情報】X-Azure-Ref= <値> / ErrorInfo=OriginTimeout / CacheStatus=MISS 多発
【暫定対応】キャッシュ維持、再試行、DNS キャッシュ更新の案内
【恒久策】マルチオリジン化・タイムアウト最適化・ウォーム戦略の導入

Front Door ルール(例:圧縮の除外で不整合回避)

// バイト範囲要求と圧縮の併用で不整合が出る場合の緩和例
IF (RequestMethod == GET AND RequestHeader("Range") exists)
THEN ResponseHeader Action: Delete "Accept-Encoding"

リリース後のプレウォーム(PowerShell 例)

$urls = @(
  "https://www.example.com/assets/app-1.2.3.js",
  "https://www.example.com/assets/app-1.2.3.css",
  "https://www.example.com/img/hero.webp"
)
$wc = New-Object Net.WebClient
$urls | % { try { $wc.DownloadString($_) | Out-Null } catch {} }

ケーススタディ:紅海ケーブル断の影響をどう読むか

2025 年 9 月 6 日(UTC)頃、紅海の複数の海底ケーブルに切断が発生し、欧州–アジア–中東を結ぶ大動脈の一部が損傷しました。Microsoft は Azure のネットワーク経路について中東経由の遅延上昇とトラフィック迂回を公表しており、クラウド全般で一時的に TTFB の上振れが観測されました。今回のように「ピーク外・数分・多地域同時・自動復旧」は、まさに広域経路の再収束パターンに合致します。こうしたイベントの際にやってはいけないのは、原因が外部にあるのにアプリ/インフラ設定を激しく変更してしまうことです。ログでOriginTimeout が PoP 横断で同時刻に立つこと、Storage の E2E − ServerLatency が跳ねることが確認できれば、まずは状況観測と利用者案内を優先し、構成変更は収束後に行うのが安全です。

チェックの深掘り:フィールド辞典(抜粋)

ログ/メトリクスキー意味/使いどころ
Front Door Access LogTimetoFirstByteエッジが初バイトを返すまでの時間。TTFB の指標。経路/オリジン遅延の感度が高い。
Front Door Access LogTimeTaken最終バイトまでの時間。大きいファイルや帯域制約の影響を受ける。
Front Door Access LogErrorInfoOriginTimeout など。真の失敗理由の特定に有効。
Front Door Access LogCacheStatusHIT/MISS/REMOTE_HIT/PARTIAL_HIT など。HIT を増やせば広域障害の影響を緩和。
Front Door Access LogPop応答した PoP(エッジ)。地域偏在の検出に。
HTTP 応答ヘッダーX-Azure-Ref追跡 ID。ユーザー報告とログの一意突合に必須。
Storage メトリクスSuccessE2ELatencyクライアント視点の平均 E2E レイテンシ(含ネットワーク)。
Storage メトリクスSuccessServerLatencyサーバー処理時間の平均(ネットワーク除外)。E2E との差で経路影響を推定。
Storage 応答ヘッダーx-ms-request-idStorage 側の要求 ID。Front Door の X-Azure-Ref と時刻で合わせ込む。

最後に:実務での「最小労力・最大効果」

  • 見える化ファースト:Front Door/Storage のダッシュボードを常設(1 分粒度)。
  • HIT を正義に:キャッシュ戦略で広域障害の波及を小さくする。
  • マルチオリジン:地理冗長で「経路ゆらぎ」に強い面を作る。
  • タイムアウト最適化:現実の p95/p99 に合わせ、障害検知とペアで調整。
  • トレース文化:X-Azure-Ref と x-ms-request-id を報告テンプレに。

本記事の要約

本ケースの 504 は、構成ミスよりも広域ネットワークの一過性遅延(海底ケーブル断線など)の可能性が高い状況証拠を持ちます。まずは Azure Status/Service Health で基盤イベントの有無を見て、Storage メトリクス(E2E/ServerLatency)と Front Door ログ(ErrorInfo=OriginTimeout・TimetoFirstByte)で技術的に裏付ける。基盤要因なら収束を待ちつつヒット率維持、自サービス要因ならオリジン性能・タイムアウト・キャッシュ/ルールで手当て。再発抑止はマルチオリジン+観測性+運用テンプレが王道です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次