michimani.net

Amazon CloudFront が Server Timing に対応したみたいなので試してみる

2022-04-01

Amazon CloudFront が Server Timing に対応したみたいなので、既存の distribution に対して設定してどんな情報が得られるのか試してみます。

Server Timing とは

This specification enables a server to communicate performance metrics about the request-response cycle to the user agent. It also standardizes a JavaScript interface to enable applications to collect, process, and act on these metrics to optimize application delivery.

Server Timing : https://w3c.github.io/server-timing/

W3C で定義されている仕様で、サーバに対するリクエスト/レスポンスに関する情報をレスポンスヘッダの Server-Timing フィールドを通じてクライアントに伝えることができるというものです。
これにより、キャッシュまたはオリジンサーバーからレスポンスを取得するのにかかった時間、リクエストがどのようにルーティングされてどこで時間が費やされたかを知ることができるようです。

Amazon CloudFront でのサポート

Starting today, you can configure your CloudFront distributions to include Server Timing headers to monitor CloudFront behavior and performance. Server Timing headers provide detailed performance information, such as whether content was served from cache when a request was received, how the request was routed to the CloudFront edge location, and how much time elapsed during each stage of the connection and response process.

Amazon CloudFront now supports Server Timing headers

CloudFront では、 ResponseHeadersPolicy の設定項目として Server Timing が追加され、 有効/無効 とサンプリングレートを設定します。

現時点 (2022/04/01) では AWS CLI の最新バージョン (1.22.86, 2.5.1) でも対応しておらず、 create-response-headers-policy および update-response-headers-policy で設定できず、 get-response-headers-policy および list-response-headers-policies のレスポンスにも設定項目の情報は含まれていません。なので、マネジメントコンソール上でのみ設定・閲覧が可能です。

設定して確認

ResponseHeadersPolicy の項目としては 有効/無効 とサンプリングレートのみで、作成した ResponseHeadersPolicy を任意の distribution の任意の behavior の Response headers policy にて設定して使います。
手順については特に新しい要素もないので割愛、とりあえずサンプリングレートは 100% で設定して確認します。

レスポンスの確認には httpie を使います。(curl もいいけど httpie のオプションが使いやすい。出力も見やすい。)

http -p hH https://michimani.net/

出力の確認

CloudFront でキャッシュヒットした場合としなかった場合とで、それぞれ Server-Timing ヘッダに含まれる値を確認してみます。
Server-Timing フィールドの値の詳細な説明については下記を参照してください。

キャッシュヒットした場合

HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 1
Cache-Control: no-store
Connection: keep-alive
Content-Length: 10871
Content-Type: text/html;charset=UTF-8
Date: Fri, 01 Apr 2022 14:34:31 GMT
ETag: "a9105ce3fc62d088f4c991060d32d77f"
Last-Modified: Thu, 17 Mar 2022 09:41:20 GMT
Server: AmazonS3
Server-Timing: cdn-cache-hit,cdn-pop;desc="NRT12-C3",cdn-rid;desc="KwMMqgb8SoVYsOfXg7IFyIfE0nTpjdjNfwpPzDPQPdv7ldjaNqTJGw==",cdn-hit-layer;desc="EDGE"
Via: 1.1 e72e0d477a3b173c0d7c54332be184a4.cloudfront.net (CloudFront)
X-Amz-Cf-Id: KwMMqgb8SoVYsOfXg7IFyIfE0nTpjdjNfwpPzDPQPdv7ldjaNqTJGw==
X-Amz-Cf-Pop: NRT12-C3
X-Cache: Hit from cloudfront
x-amz-server-side-encryption: AES256

カンマ区切りで情報が含まれています。

cdn-cache-hit,
cdn-pop;desc="NRT12-C3",
cdn-rid;desc="KwMMqgb8SoVYsOfXg7IFyIfE0nTpjdjNfwpPzDPQPdv7ldjaNqTJGw==",
cdn-hit-layer;desc="EDGE"

cdn-cache-hit

キャッシュヒットしたことがわかります。

cdn-pop;desc=“NRT12-C3”

CloudFront のどの POP (point of presence) がリクエストを処理したか。
NRT は成田空港の IATA コードなので、そのあたりのエッジが処理したと思われる。

cdn-rid;desc=“KwMMqgb8SoVYsOfXg7IFyIfE0nTpjdjNfwpPzDPQPdv7ldjaNqTJGw==”

リクエスト ID。トラブルシュート用。

cdn-hit-layer;desc=“EDGE”

キャッシュヒットしたレイヤー。CloudFront がオリジンにリクエストを行わずにキャッシュからのレスポンスを返す場合に含まれる値。
この場合 EDGE なので POP のキャッシュにヒットしていることがわかります。

キャッシュミスヒットの場合

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-store
Connection: keep-alive
Content-Length: 10871
Content-Type: text/html;charset=UTF-8
Date: Fri, 01 Apr 2022 14:34:06 GMT
ETag: "a9105ce3fc62d088f4c991060d32d77f"
Last-Modified: Thu, 17 Mar 2022 09:41:20 GMT
Server: AmazonS3
Server-Timing: cdn-upstream-layer;desc="EDGE",cdn-upstream-dns;dur=0,cdn-upstream-connect;dur=9,cdn-upstream-fbl;dur=78,cdn-cache-miss,cdn-pop;desc="NRT12-C3",cdn-rid;desc="0_6wUpeXAmA-0HC9ZWaMp9MnPjjlhtC4PmP7bHkfXXqYt-bMIxz5tw=="
Via: 1.1 823128cacec2b9d382c65187bf76768e.cloudfront.net (CloudFront)
X-Amz-Cf-Id: 0_6wUpeXAmA-0HC9ZWaMp9MnPjjlhtC4PmP7bHkfXXqYt-bMIxz5tw==
X-Amz-Cf-Pop: NRT12-C3
X-Cache: Miss from cloudfront
x-amz-server-side-encryption: AES256
cdn-upstream-layer;desc="EDGE",
cdn-upstream-dns;dur=0,
cdn-upstream-connect;dur=9,
cdn-upstream-fbl;dur=78,
cdn-cache-miss,
cdn-pop;desc="NRT12-C3",
cdn-rid;desc="0_6wUpeXAmA-0HC9ZWaMp9MnPjjlhtC4PmP7bHkfXXqYt-bMIxz5tw=="

cdn-upstream-layer;desc=“EDGE”

CloudFront がオリジンに対してレスポンスをリクエストしたときに含まれる値。
この場合、 POP がオリジンに対してリクエストを送信したことがわかります。

cdn-upstream-dns;dur=0

オリジンの DNS レコードの取得にかかった時間 (ミリ秒) 。
0 の場合、 CloudFront がキャッシュしている DNS を結果を使用したか、既存の接続を再利用したことを示します。

cdn-upstream-connect;dur=9

オリジンの DNS 解決が完了してからオリジンへの TCP 接続が完了するまでにかかった時間 (ミリ秒) 。

cdn-upstream-fbl;dur=78

オリジンへの HTTP リクエストが完了してから、最初のバイト列が返ってくるまでにかかった時間 (ミリ秒) 。 (fbl = first byte latency)

cdn-cache-miss

キャッシュヒットせず、オリジンに対してリクエストしています。

cdn-pop;desc=“NRT12-C3”

CloudFront のどの POP (point of presence) がリクエストを処理したか。
NRT は成田空港の IATA コードなので、そのあたりのエッジが処理したと考えられます。

cdn-rid;desc=“0_6wUpeXAmA-0HC9ZWaMp9MnPjjlhtC4PmP7bHkfXXqYt-bMIxz5tw==”

リクエスト ID。トラブルシュート用。

まとめ

CloudFront が ServerTiming に対応して、諸々の情報がレスポンスヘッダから取得できるようになりました。
特に、キャッシュヒットしなかった場合にオリジンとの接続にかかった時間、オリジンからレスポンスが返ってくるまでにかかった時間がわかるようになったことで、パフォーマンス改善のための一つの情報として役に立ちそうです。

AWS CLI/AWS SDK/Terraform で ResponseHeadersPolicy の設定項目を定義・閲覧できるようになったらまた試します。

参考


comments powered by Disqus