Amazon CloudFrontがCDN-オリジン間のパフォーマンスを計測するServer Timingに対応しました
Webサーバーのパフォーマンスを計測する Server Timing という規格が W3Cによって策定されており、サーバーが決められたフォーマットでメトリクスをレスポンスに含めると、Server Timing に対応したブラウザからメトリクスを簡単に確認できます。
この仕様のエディターは、Akamai と Google のエンジニアであり、Akamai の CDN では何年も前から Server Timing を有効にでき、Chrome ブラウザからメトリクスを確認できました。
Using CDN Server Timing to Monitor CDN and Origin Performance | Akamai Developer
今回のアップデートにより、Amazon CloudFront もCDN-オリジン間の通信に対してこの Server Timing を返せるようになりました。
- Announcing AWS Lambda Function URLs: Built-in HTTPS Endpoints for Single-Function Microservices | AWS News Blog
- Amazon CloudFront now supports Server Timing headers
やってみた
Server Timing を返すには、Server Timing を有効にしたカスタム・レスポンス・ヘッダー・ポリシーを作成し、Behaviorに適用します。
レスポンス・ヘッダー・ポリシーの作成
レスポンス・ヘッダー・ポリシー の設定画面に Server-Timing header の項目が追加されています。
これを有効化(Enable)し、サンプリングレートを0−100の範囲で指定します。
レートはレスポンスに Server Timing ヘッダーを含める割合です。
特殊なリクエストを送信すると、レートによらずに、強制的に Server Timing ヘッダーを含めることもできます。
Behaviorにポリシーの適用
Behavior の Response headers policy で作成したポリシーを適用します。
レスポンスを確認
CloudFrontにアクセスして Server Timingレスポンスを確認します。
レスポンスヘッダーに Server Timing 用の
server-timing: key1;value1,key2;value2,...
というヘッダーが追加されています。
キャッシュミス時
accept-ranges: bytes content-length: 14 content-type: text/html date: Thu, 31 Mar 2022 19:57:48 GMT etag: "910c8bc73110b0cd1bc5d2bcae782511" last-modified: Wed, 20 Jan 2021 14:43:24 GMT server: AmazonS3 server-timing: cdn-upstream-layer;desc="EDGE",cdn-upstream-dns;dur=0,cdn-upstream-connect;dur=41,cdn-upstream-fbl;dur=74,cdn-cache-miss,cdn-pop;desc="TXL52-C1",cdn-rid;desc="O7AyjtKd7IwOozuiFo0cvztVcPE3nUuQTSyl3_QBOoTAQvm1HvQmdQ==" via: 1.1 81db6db0bc548ca5046f3395364a3666.cloudfront.net (CloudFront) x-amz-cf-id: O7AyjtKd7IwOozuiFo0cvztVcPE3nUuQTSyl3_QBOoTAQvm1HvQmdQ== x-amz-cf-pop: TXL52-C1 x-cache: Miss from cloudfront
このレスポンスの server-timing からは、
- リクエストがキャッシュミスしたこと (
cdn-cache-miss
) - POP がオリジンにリクエストしたこと (
cdn-upstream-layer;desc="EDGE"
) - コネクションの確立に41ミリ秒、TTFB(first byte latency)に74ミリ秒要したこと (
cdn-upstream-connect;dur=41,cdn-upstream-fbl;dur=74
)
などがわかります。
キャッシュヒット時
HTTP/2 200 content-type: text/html content-length: 14 date: Thu, 31 Mar 2022 20:06:02 GMT last-modified: Wed, 20 Jan 2021 14:43:24 GMT etag: "910c8bc73110b0cd1bc5d2bcae782511" accept-ranges: bytes server: AmazonS3 x-cache: Hit from cloudfront via: 1.1 89507e1fe7f6498a3cc1e132cbae3e50.cloudfront.net (CloudFront) x-amz-cf-pop: TXL50-P2 x-amz-cf-id: WRaaEVfOxkZ_Y1nuQLkMQa4xyMGtjnaHpq3DBPk_l5ST7OTZbcEXLg== age: 18 server-timing: cdn-cache-hit,cdn-pop;desc="TXL50-P2",cdn-rid;desc="WRaaEVfOxkZ_Y1nuQLkMQa4xyMGtjnaHpq3DBPk_l5ST7OTZbcEXLg==",cdn-hit-layer;desc="EDGE"
このレスポンスの server-timing からは、
- リクエストがキャッシュヒットしたこと (
cdn-cache-hit
) - POP がキャッシュヒットしたこと (
cdn-hit-layer;desc="EDGE"
)
などがわかります。
キャッシュヒット時はオリジンへのリクエストが発生しないので、cdn-upstream-xxx
系の値は存在しません。
フィールドの詳細はドキュメントをご確認ください。
Understanding response headers policies - Amazon CloudFront
cdn-upstream-xxx の読み取り方
CloudFront の server timing 用のメトリックとして
- cdn-upstream-dns : Contains a value with the number of milliseconds that were spent retrieving the DNS record for the origin. A value of zero (0) indicates that CloudFront used a cached DNS result or reused an existing connection.
- cdn-upstream-connect : Contains a value with the number of milliseconds between when the origin DNS request completed and a TCP (and TLS, if applicable) connection to the origin completed. A value of zero (0) indicates that CloudFront reused an existing connection.
- cdn-upstream-fbl : Contains a value with the number of milliseconds between when the origin HTTP request is completed and when the first byte is received in the response from the origin (first byte latency).
が存在します。
cdn-upstream-fbl
の解釈には注意が必要です。
メトリック名から類推すると、sever timing の cdn-upstream-fbl
は Chrome Timing の Waiting(TTFB)
と同等の意味と解釈したくなります。
具体的には、キャッシュミス時には、オリジンへのリクエストが発生するため、ビューアーがエッジにリクエストを投げてからレスポンスが戻ってくるまで(=Waiting(TTFB))の時間内にCloudFrontからオリジンへのリクエストが行われるはずで、下図のようになることを期待したくなります。
改めて Chrome の Dev Tools からメトリクスを確認すると
Waiting(TTFB)[85.52 ms] < cdn-upstream-dns[0 ms] + cdn-upstream-connect[41.00 ms] + cdn-upstream-fbl[74.00 ms]
となっています。
CloudFrontからオリジンへのリクエスト処理時間(cdn-upstream-xxx
の合計)がTTFBを超えるのはおかしいですね。
cdn-upstream-fbl
は DNS 名前解決や TCP スリーウェイハンドシェイクや TLS ハンドシェイクの時間 (つまり cdn-upstream-dns
や cdn-upstream-connect
) も含んでいるためです。
TTFB
のように、リクエスト完了後にレスポンスが戻ってくるまでの時間ではないことに注意しましょう。
※ AWS サポートで定義を確認済み
強制的に server timing を返す
レスポンスに server timing を含める割合は、ポリシーのサンプリングレートで指定します。
サンプリングレートに100以外の値を設定すると、レスポンスによっては server timing が含まれないことがあります。 極端な例では、サンプリングレートを0にすると、通常は server timing が一切含まれません。
リクエストヘッダーに Pragma: server-timing
を渡すと、強制的に server timing をかえすことができます。
$ curl \ -H "Pragma: server-timing" \ -I https://example.com/index.html
まとめ
Amazon CloudFront がServer Timingに対応し、オリジンとの通信の様々なインサイトをレスポンスヘッダーから得られるようになりました。
アクセスログに依存することが多かったパフォーマンスのモニタリングも、今後は Server Timing と補完し合うことになるでしょう。
クライアントが得られる情報が大幅に増えるため、トラブルシュートが捗るのではないかと思います。
それでは。