失効済みコンテンツの配信

Fastly では、オリジンサーバーに問題が発生している時、またはオリジンサーバーからの新しいコンテンツの取得に長い時間を要している場合に、失効済みコンテンツを配信するよう設定することができます。例えば、Fastly からオリジンサーバーに接続できない場合、Fastly POP はユーザーのリクエストに対してキャッシュ済みコンテンツの配信を続けます。これらの機能は既定では有効になっていません。

ヒント

失効済みコンテンツの配信に関する詳細は、失効済みコンテンツと再検証に関するドキュメントを参照してください。

新しいコンテンツの取得中に古いコンテンツを配信する

コンテンツの種類によっては、生成に時間がかかるものもあります。一度キャッシュされたコンテンツはすぐに配信されますが、最初にアクセスしようとしたユーザーはコンテンツが生成されるのを待たなければなりません。

キャッシング時間のペナルティ

これはコールドキャッシュの場合には避けられないことですが、オブジェクトがキャッシュにあり、 TTL が期限切れになっている時にこのようなことが起こるのであれば、Fastly は新しいコンテンツがバックグラウンドでフェッチされている間、失効済みコンテンツを表示するように設定することができます。

バックグラウンドで新しいコンテンツを取得する

Fastly は、Google Chrome ブラウザへの搭載が検討されている Mark Nottingham 氏の RFC 5861 『HTTP Cache-Control Extensions for Stale Content』 で提案された動作をベースにしています。

失効済みの配信を有効にする

注意

すでにカスタム VCL でエラー時の失効済みコンテンツの配信を有効にしている場合、コントロールパネルでこの機能を追加すると、別の失効済み TTL が設定されます。これを回避するため、コントロールパネルでこの機能を有効化する前に、stale-if-error ステートメントをカスタム VCL から削除してください。

コントロールパネルを介したエラーで、デフォルト TTL 期間 (43200秒または12時間) での失効済みコンテンツの配信を有効にするには、以下の手順に従ってください。

  1. Fastly コントロールパネルにログインします。
  2. Home ページから、適切なサービスを選択します。検索ボックスで ID、名称、ドメインによる検索が行えます。
  3. Edit configuration をクリックし、アクティブなバージョンをクローンするオプションを選択します。
  4. Settings をクリックします。

    失効済みの配信をオンにする

  5. Serve stale スイッチをオンにすると、デフォルト TTL 期間である43200秒 (12時間) の間、失効済みコンテンツの配信が自動的に有効になります。

  6. Activate をクリックして設定への変更をデプロイします。

手動で失効済みの配信を有効にする

この手順では、3つのオリジンサーバーの障害のシナリオにて VCL を使って対応するための高度な設定を行います。

Varnish の場合、オリジン/オリジンサーバー障害には3つのケースが考えられます。

  • ヘルスチェックの失敗により、オリジン/オリジンサーバーに異常があると見なされる。
  • 何らかの理由で Varnish がオリジン/オリジンサーバーに接続できない場合、503エラーが発生する。
  • オリジンからの HTTP レスポンスが、ユーザーへの配信に適さない内容である (503エラーなど)。

下記のカスタム VCL はこれら3種類のケースすべてに対応します。オリジンのヘルスステータスが異常の場合、デフォルトサーバーの執行済み動作がstale-if-errorによって開始されます。オリジン/オリジンサーバー障害の発生からオリジンのヘルスステータスが異常と見なされるまでの間、Varnish は通常503 エラーを返します。カスタム VCL を使用することで、失効済みのコピーがある場合には、代わりに失効済みを配信するか、シンセティックエラーページを返すことができます。エラーページはカスタマイズすることができます。3つ目のケースでは、vcl_fetch での 5XX エラーを遮断し、失効済みコンテンツを配信するか、シンセティックエラーページを配信することで対応することができます。

警告

503エラーが発生している場合、キャッシュされたコンテンツをすべてパージすることは避けてください。全コンテンツのパージを行うと stale-if-error がオーバーライドされ、オリジンサーバーへのリクエスト数が増加します。その結果、503エラーがさらに増える可能性があります。

必須ではありませんが、この VCL と一緒にヘルスチェック機能を有効にしてください。ヘルスチェックを有効にしていない場合でもすべての機能は動作しますが、失効済みのレスポンスやシンセティックレスポンスの配信には、オリジンのタイムアウトを待たなくてはいけないため、より長い時間がかかります。ヘルスチェックを有効にすると、オリジンが不健全であるとマークされるため、この問題は回避されます。

以下のカスタム VCL は、Fastly 標準のボイラープレートを含んでいます。お客様のサービスにアップロードする前に、必要に合わせて以下の値をカスタマイズまたは削除してください。

  • if (beresp.status >= 500 && beresp.status < 600) は、失効済みコンテンツやシンセティックレスポンスを配信すべき HTTP レスポンスコードを含むように変更する必要があります。
  • set beresp.stale_if_error = 86400s; は、失効済みコンテンツが配信される期間を制御します。この値は、設定に応じて適切な値に設定する必要があります。オリジンから Surrogate-Control または Cache-Control にて stale_if_error を送信している場合は、この行全体を削除します。
  • set beresp.stale_while_revalidate = 60s;これは、オブジェクトstale_while_revalidateに対して機能が有効になる時間を制御するもので、設定に意味のある量に設定する必要があります。この機能により、Varnish はキャッシュミスの際に執行済みとなり、バックグラウンドでオリジンから最新バージョンのオブジェクトを取得するようになります。これにより、TTL の短いオブジェクトや、一般的なキャッシュミスの際に、大きなパフォーマンスの向上が期待できます。 stale_while_revalidateは、 stale_if_errorによって上書きされるので注意してください。つまり、オブジェクトが再検証中に失効済み(キャッシュしてからTTLに設定された時間が経過した)状態で配信される資格がある限り、stale_if_error の効果はありません。オリジンから Surrogate-Control または Cache-Control にて stale_while_revalidate を送信している場合は、この行全体を削除します。
  • synthetic {"<!DOCTYPE html>Your HTML!</html>"}; は、失効済みバージョンのオブジェクトが存在しない場合に Varnish が返すシンセティックレスポンスであり、設定に応じて適切に設定する必要があります。ここには、お客様の HTML、CSS、JS を埋め込むことができます。外部の CSS や JS ドキュメントを参照する際には注意が必要です。オリジンがオフラインの場合は、それらも利用できない可能性があります。
1sub vcl_recv {
2#FASTLY recv
3 # Normally, you should consider requests other than GET and HEAD to be uncacheable
4 # (to this we add the special FASTLYPURGE method)
5 if (req.method != "HEAD" && req.method != "GET" && req.method != "FASTLYPURGE") {
6 return(pass);
7 }
8 # If you are using image optimization, insert the code to enable it here
9 # See https://www.fastly.com/documentation/reference/io/ for more information.
10 return(lookup);
11}
12sub vcl_hash {
13 set req.hash += req.url;
14 set req.hash += req.http.host;
15 #FASTLY hash
16 return(hash);
17}
18sub vcl_hit {
19#FASTLY hit
20 return(deliver);
21}
22sub vcl_miss {
23#FASTLY miss
24 return(fetch);
25}
26sub vcl_pass {
27#FASTLY pass
28 return(pass);
29}
30sub vcl_fetch {
31 /* handle 5XX (or any other unwanted status code) */
32 if (beresp.status >= 500 && beresp.status < 600) {
33 /* deliver stale if the object is available */
34 if (stale.exists) {
35 return(deliver_stale);
36 }
37 if (req.restarts < 1 && (req.method == "GET" || req.method == "HEAD")) {
38 restart;
39 }
40 }
41 /* set stale_if_error and stale_while_revalidate (customize these values) */
42 set beresp.stale_if_error = 86400s;
43 set beresp.stale_while_revalidate = 60s;
44#FASTLY fetch
45 /* handle 5XX (or any other unwanted status code) */
46 if (beresp.status >= 500 && beresp.status < 600) {
47 /* deliver stale if the object is available */
48 if (stale.exists) {
49 return(deliver_stale);
50 }
51 # Unset headers that reduce cacheability for images processed using the Fastly image optimizer
52 if (req.http.X-Fastly-Imageopto-Api) {
53 unset beresp.http.Set-Cookie;
54 unset beresp.http.Vary;
55 }
56 # Log the number of restarts for debugging purposes
57 if (req.restarts > 0) {
58 set beresp.http.Fastly-Restarts = req.restarts;
59 }
60 # If the response is setting a cookie, make sure it is not cached
61 if (beresp.http.Set-Cookie) {
62 return(pass);
63 }
64 # By default we set a TTL based on the `Cache-Control` header but we don't parse additional directives
65 # like `private` and `no-store`. Private in particular should be respected at the edge:
66 if (beresp.http.Cache-Control ~ "(?:private|no-store)") {
67 return(pass);
68 }
69 # If no TTL has been provided in the response headers, set a default
70 if (!beresp.http.Expires && !beresp.http.Surrogate-Control ~ "max-age" && !beresp.http.Cache-Control ~ "(?:s-maxage|max-age)") {
71 set beresp.ttl = 3600s;
72 # Apply a longer default TTL for images processed using Image Optimizer
73 if (req.http.X-Fastly-Imageopto-Api) {
74 set beresp.ttl = 2592000s; # 30 days
75 set beresp.http.Cache-Control = "max-age=2592000, public";
76 }
77 }
78 return(deliver);
79}
80sub vcl_error {
81#FASTLY error
82 /* handle 503s */
83 if (obj.status >= 500 && obj.status < 600) {
84 /* deliver stale object if it is available */
85 if (stale.exists) {
86 return(deliver_stale);
87 }
88 /* otherwise, return a synthetic */
89 /* include your HTML response here */
90 synthetic {"<!DOCTYPE html><html>Replace this text with the error page you would like to serve to clients if your origin is offline.</html>"};
91 return(deliver);
92 }
93}
94sub vcl_deliver {
95#FASTLY deliver
96 return(deliver);
97}
98sub vcl_log {
99#FASTLY log
100}

ヘッダーを追加する

カスタム VCL を追加すると、オリジンサーバーからのレスポンス内の Cache-Control または Surrogate-Control ヘッダーのいずれかに、stale-while-revalidate または stale-if-error ディレクティブを追加することで、失効済みコンテンツの配信を手動で有効化することができます。 例:

Cache-Control: max-age=600, stale-while-revalidate=30

この例では、一部のコンテンツを10分間キャッシュした後、新しいコンテンツが取得されるまでの間、最大30秒間失効済みコンテンツを配信するようになっています。

同様に、 こちらのステートメント:

Surrogate-Control: max-age=3600, stale-if-error=86400

では、キャッシュのコンテンツを1時間 (3600 秒) 毎に更新しますが、オリジンがダウンしている場合は期限切れのコンテンツを1日間 (86400 秒) 表示するようになっています。

また、vcl_fetchにて以下の変数を設定することで、VCL 内からこれらの動作を制御することもできます。。

set beresp.stale_while_revalidate = 30s;
set beresp.stale_if_error = 86400s;

grace によるインタラクション

Stale-if-error は、Varnish の変数 grace と全く同じ働きをするので、この2つの記述は同等です。

set beresp.grace = 86400s;
set beresp.stale_if_error = 86400s;

ただし、VCL に grace のステートメントがある場合は、Cache-Control や Surrogate-Control のレスポンスヘッダー内の stale-if-error ステートメントをオーバーライドします。

失効済みコンテンツの配信が期待通りにいかない理由

Fastly からの失効済みコンテンツの配信が行われない場合、以下のポイントを確認してください。

  • キャッシュ: 失効済みオブジェクトは、キャッシュ可能なコンテンツにのみ有効です。
  • VCL: req.hash_always_miss または req.hash_ignore_busy の変数を true にすると、stale-while-revalidate の効果が無効になります。
  • オリジンシールド:オリジンシールドを有効にしていない場合、POPは、そのキャッシュ可能なオブジェクトへのリクエストが以前にそのPOPを介して行われた場合にのみ、エラー時に執行済みとなります。エラー発生時に失効済みコンテンツがキャッシュされる確率を高めるため、オリジンシールドを有効にすることを推奨します。オリジンシールドはまた、全コンテンツのパージ実行後に速やかにコンテンツをキャッシュさせるためにも効果的です。
  • リクエスト: サイトへのトラフィックが増加すると、オリジンシールドが無効な場合でも、失効済みオブジェクトが利用可能になる可能性が高くなります。人気のあるコンテンツならば、複数の POP にてキャッシュされることもあります。
  • 最近使用していない場合(LRU):Fastly は LRU リストを採用しているため、オブジェクトは TTL (キャッシュ保持時間) の期間中に継続的にキャッシュを保持することを必ずしも保証しません。キャッシュの保持と削除は、ファイルに対するリクエストの頻度、TTL の値、ファイルの配信元となる POP など、数多くの要因を踏まえて行われます。例えば、3700秒以上の TTL のファイルがディスクへ保管される一方で、3700秒未満の TTL の場合はメモリーのみに一時的に保管されます。TTL は可能な限り3700秒以上に設定することをお勧めします。
  • パージ: パージの際は、可能な限りソフトパージを実行してコンテンツをバージしください。ソフトパージでは、Fastly のキャッシュからコンテンツを永久に削除するのではなく、古い (失効済み) コンテンツとして簡単にマークすることができます。ソフトパージが不可能ならば、全コンテンツのパージをできる限り避けて、URL によるパージキーによるパージの活用を推奨します。

翻訳についての注意事項
このガイドは役に立ちましたか?

このフォームを使用して機密性の高い情報を送信しないでください。サポートが必要な場合は、サポートチームまでご連絡ください。このフォームは reCAPTCHA によって保護されており、Google のプライバシーポリシー利用規約が適用されます。