0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Cloudflare でステータスコードごとの Edge Cache TTL を確認する

Last updated at Posted at 2023-08-21

ステータスコードごとの Edge Cache TTL

Cloudflare では、ステータスコードごとの Edge Cache TTL を設定できます。

デフォルトでは、Cloudflare は cache-control ディレクティブや expires レスポンスヘッダが存在しない場合、特定の HTTP レスポンスコードを以下の Edge Cache TTL でキャッシュします。

HTTP status code Default TTL
200, 206, 301 120m
302, 303 20m
404, 410 3m
403 0s
500, 502, 503, 504 0s

Default TTL = 0s の場合は、デフォルトではリソースをキャッシュしない形になります。

Cloudflareは、Edge Cache TTLページルールがヘッダを上書きしない限り、オリジンウェブサーバのキャッシュヘッダを以下の順序で尊重します。
Cloudflareは以下の場合、リソースをキャッシュしません:
Cache-Control ヘッダが private、no-store、no-cache、または max-age=0 に設定されている場合。

オリジンの準備

以下の要領でオリジンサーバーを準備します。

その上で特定のステータスコードを返す HTML ページを用意します。

400.html
<?php http_response_code(400);  ?>
<!DOCTYPE html>
<html>

<head>
    <title>php-generated 400</title>
</head>

<body>
    This is a 400 error page.
</body>

</html>

.html をキャッシュする設定

HTML はデフォルトでキャッシュされないため、Cache Rules を使ってキャッシュする設定にしておきます。

  • When incoming requests match…
    • (http.request.uri.path.extension eq "html")

image.png

Status code TTL 設定

デフォルト設定から変更したい場合、Cache Rules を使って、例えば以下のように設定できます。

image.png

400 で確認

while true; do curl -sIXGET https://example.com/400.html | grep -e cf-cache-status: -e age: -e HTTP -e cache-control: && sleep 3; done

デフォルト = 0s

HTTP/2 400 
cf-cache-status: MISS
HTTP/2 400 
cf-cache-status: MISS
HTTP/2 400 
cf-cache-status: MISS

Status code TTL = 30s

Status code TTL 設定が反映されたことがわかります。

HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: EXPIRED
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 3
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 6
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 3
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 9
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 12
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 25
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: EXPIRED
HTTP/2 400 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 6

403 で確認

while true; do curl -sIXGET https://example.com/403.html | grep -e cf-cache-status: -e age: -e HTTP -e cache-control: && sleep 3; done

(.htaccess などのパスを使って確認するのもありです。)

デフォルト = 0s

HTTP/2 403 
cf-cache-status: MISS
HTTP/2 403 
cf-cache-status: MISS
HTTP/2 403 
cf-cache-status: MISS

Status code TTL = 30s

Status code TTL 設定が反映されたことがわかります。

HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: MISS
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 3
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 6
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 9
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 12
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 15
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 21
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 24
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 28
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: EXPIRED
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
HTTP/2 403 
cache-control: max-age=31536000
cf-cache-status: HIT
age: 6

404 で確認

while true; do curl -sIXGET https://example.com/404.html | grep -e cf-cache-status: -e age: -e HTTP -e cache-control: && sleep 3; done

(実際には存在しないパスを使って確認するのもありです。)

デフォルト = 180s

HTTP/2 404 
cf-cache-status: MISS
cache-control: public, max-age=14400
HTTP/2 404 
cf-cache-status: HIT
cache-control: public, max-age=14400
HTTP/2 404 
cf-cache-status: HIT
age: 7
cache-control: public, max-age=14400
...
HTTP/2 404 
cf-cache-status: HIT
age: 174
cache-control: public, max-age=14400
HTTP/2 404 
cf-cache-status: EXPIRED
cache-control: public, max-age=14400
HTTP/2 404 
cf-cache-status: HIT
age: 174
cache-control: public, max-age=14400
HTTP/2 404 
cf-cache-status: HIT
age: 9
cache-control: public, max-age=14400
HTTP/2 404 
cf-cache-status: HIT
age: 10
cache-control: public, max-age=14400

Status code TTL = -1 (no store)

Status code TTL 設定が反映されたことがわかります。

HTTP/2 404 
cache-control: public, max-age=31536000
cf-cache-status: MISS
HTTP/2 404 
cache-control: public, max-age=31536000
cf-cache-status: MISS
HTTP/2 404 
cache-control: public, max-age=31536000
cf-cache-status: MISS

502 で確認

while true; do curl -sIXGET https://example.com/502.html | grep -e cf-cache-status: -e age: -e HTTP -e cache-control: && sleep 3; done

デフォルト = 0s

HTTP/2 502 
cf-cache-status: MISS
HTTP/2 502 
cf-cache-status: MISS
HTTP/2 502 
cf-cache-status: MISS

Status code TTL = 1s

STALE 状態で返してしまいます。

HTTP/2 502 
cache-control: max-age=31536000
cf-cache-status: MISS
HTTP/2 502 
cache-control: public, max-age=0
cf-cache-status: STALE
age: 3
HTTP/2 502 
cache-control: public, max-age=0
cf-cache-status: STALE
age: 6
HTTP/2 502 
cache-control: max-age=31536000
cf-cache-status: STALE
HTTP/2 502 
cache-control: public, max-age=0
cf-cache-status: STALE
age: 12

Amazon CloudFront の場合、以下のような挙動がドキュメントで公開されていますが、Cloudflare でも同様の挙動となっています。

  • コンテンツがキャッシュに保持される期間 (有効期限) の管理 - Amazon CloudFront
    オリジンが接続不能で、さらに最小 TTL が 0 より大きい場合、CloudFront は、先にオリジンから取得済みのオブジェクトを返信します。この動作を回避するには、Cache-Control: stale-if-error=0 ディレクティブに、オリジンから返されたオブジェクトを含めます。このようにすることで、オリジンが接続不能な場合に CloudFront が以後のリクエストに応答する際、以前にオリジンから取得したオブジェクトを返すのではなくエラーを返すようになります。
  • Origin Cache Control · Cloudflare Cache (CDN) docs
    stale-if-error=seconds — Indicates that when an error is encountered, a cached stale response may be used to satisfy the request, regardless of other freshness information. To avoid this behavior, include stale-if-error=0 directive with the object returned from the origin.

Status code TTL = 1s + stale-if-error=0

stale-if-error ディレクティブを使うことで、オリジンがエラーステータス(ステータスコード 500, 502, 503, 504)を応答する場合に一定期間は古いキャッシュを使用できますが、 STALE を使用したくない場合にはオリジン側で stale-if-error=0 を明示的に追加して無効化することで意図した通りの挙動にできました。

HTTP/2 502 
cache-control: max-age=315360000, public, stale-if-error=0
cf-cache-status: EXPIRED
HTTP/2 502 
cache-control: max-age=315360000, public, stale-if-error=0
cf-cache-status: HIT
age: 1
HTTP/2 502 
cache-control: max-age=315360000, public, stale-if-error=0
cf-cache-status: EXPIRED
HTTP/2 502 
cache-control: max-age=315360000, public, stale-if-error=0
cf-cache-status: HIT
HTTP/2 502 
cache-control: max-age=315360000, public, stale-if-error=0
cf-cache-status: EXPIRED
HTTP/2 502 
cache-control: max-age=315360000, public, stale-if-error=0
cf-cache-status: HIT
age: 1

まとめ

Cloudflare でステータスコードごとの Edge Cache TTL を確認することができました。
いくつか簡単なページを用意して意図した挙動を再現させることができれば、自信を持ってキャッシュ実装に進めると思います。

参考 : Apache オリジンでの Cache-Control ヘッダ追加

/etc/httpd/conf/httpd.conf
Header always append Cache-Control "max-age=315360000, public, stale-if-error=0"
# Header always append Cache-Control "max-age=31536000"
# Header always append Cache-Control "max-age=0"

参考 : Single File Purge

参考 : Purge Everything

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?