Azure Storage の静的ウェブサイトをオリジンにし、Microsoft CDN(現行の Azure Front Door Standard/Premium ベース)で配信していると、ピーク外でも数分だけ一部リソースが 504 Gateway Timeout を返して自然復旧する──そんな「つかみどころのない」事象に悩まされることがあります。本稿では、2025年の海底ケーブル断線に伴う広域ネットワーク収束の影響を含め、原因の芯を言語化し、Azure ポータル/ログ/KQL/クライアント検証を使った再現性ある確認・対処手順と再発抑止の設計を、実務目線の HTML 記事でまとめます。
想定構成と現象の整理
| 項目 | 内容 |
|---|---|
| オリジン | Azure Storage(静的ウェブサイト機能) |
| CDN | Microsoft 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 Log | TimetoFirstByte | エッジが初バイトを返すまでの時間。TTFB の指標。経路/オリジン遅延の感度が高い。 |
| Front Door Access Log | TimeTaken | 最終バイトまでの時間。大きいファイルや帯域制約の影響を受ける。 |
| Front Door Access Log | ErrorInfo | OriginTimeout など。真の失敗理由の特定に有効。 |
| Front Door Access Log | CacheStatus | HIT/MISS/REMOTE_HIT/PARTIAL_HIT など。HIT を増やせば広域障害の影響を緩和。 |
| Front Door Access Log | Pop | 応答した PoP(エッジ)。地域偏在の検出に。 |
| HTTP 応答ヘッダー | X-Azure-Ref | 追跡 ID。ユーザー報告とログの一意突合に必須。 |
| Storage メトリクス | SuccessE2ELatency | クライアント視点の平均 E2E レイテンシ(含ネットワーク)。 |
| Storage メトリクス | SuccessServerLatency | サーバー処理時間の平均(ネットワーク除外)。E2E との差で経路影響を推定。 |
| Storage 応答ヘッダー | x-ms-request-id | Storage 側の要求 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)で技術的に裏付ける。基盤要因なら収束を待ちつつヒット率維持、自サービス要因ならオリジン性能・タイムアウト・キャッシュ/ルールで手当て。再発抑止はマルチオリジン+観測性+運用テンプレが王道です。

コメント