Cloud CDN のトラブルシューティング

Cloud CDN の使用中に次の問題が発生したときに役立つトラブルシューティング手順について説明します。

発生している問題が外部バックエンドに関連している場合は、外部バックエンドとインターネット NEG に関する問題のトラブルシューティングもご覧ください。

全般的な問題と解決策

レスポンスがキャッシュに保存されない

レスポンスがキャッシュに保存されない場合は、初めに、バックエンド サービスまたはバックエンド バケットに対して Cloud CDN が有効化されていることを確認してください。Cloud CDN を有効にしてから、レスポンスがキャッシュに保存されるようになるまでに数分ほどかかることがあります。

Cloud CDN がキャッシュに保存するのは、キャッシュに保存可能なコンテンツを含むレスポンスだけです。この情報は、バックエンド構成と一緒に HTTP レスポンス ヘッダーに含まれます。URL のレスポンスがキャッシュに保存されない場合は、その URL に対して返されたヘッダーと、バックエンドでキャッシュが構成される方法を確認します。

レスポンス ヘッダーを確認する方法はいくつかあります。

次の例は、curl を使用して http://example.com/style.css の HTTP レスポンス ヘッダーを確認する方法を示しています。

curl -s -D - -o /dev/null http://example.com/style.css

出力:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:00 GMT
Content-Type: text/css
Content-Length: 1977
Via: 1.1 google

これらのヘッダーとキャッシュに保存可能なコンテンツの要件を比較すると、必須の Cache-Control ヘッダーがレスポンスの中にないことがわかります(キャッシュ モードUSE_ORIGIN_HEADERS に設定されていると想定した場合)。

ヘッダーを設定する方法は、送信元サーバーのタイプによって異なります。Compute Engine でウェブサーバーを実行している場合は、ウェブサーバー ソフトウェアのドキュメントでレスポンス ヘッダーの構成方法をご覧ください。Cloud Storage の場合は、オブジェクトが一般公開と設定されていれば適切なヘッダーが送信されます。

送信元サーバーの構成を変更して必須のヘッダーを追加した後に、curl をもう一度使用して結果を確認します。

curl -s -D - -o /dev/null http://example.com/style.css

出力:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:30 GMT
Content-Type: text/css
Content-Length: 1977
Cache-Control: max-age=86400,public
Via: 1.1 google
curl -s -D - -o /dev/null http://example.com/style.css

出力:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:31 GMT
Content-Type: text/css
Content-Length: 1977
Cache-Control: max-age=86400,public
Via: 1.1 google
curl -s -D - -o /dev/null http://example.com/style.css

出力:

HTTP/1.1 200 OK
Date: Tue, 16 Feb 2016 12:00:30 GMT
Content-Type: text/css
Content-Length: 1977
Cache-Control: max-age=86400,public
Via: 1.1 google
Age: 2

この例の最後のレスポンスには Age ヘッダーが含まれています。Cloud CDN は、キャッシュから提供されたレスポンスに Age ヘッダーを追加します。このヘッダーは、2 秒前に作成されたキャッシュ エントリを使用して、レスポンスがキャッシュから正常に提供されたことを表しています。

さらに、バックエンド インスタンスで ETag が有効になっている場合、Cloud CDN はオブジェクトの鮮度を確認するために ETag を使用します。バックエンド インスタンスが同じオブジェクトに対して異なる ETag を配信する場合、Cloud CDN は不一致をキャッシュミスとしてカウントし、オブジェクトを更新します。これを防ぐには、バックエンド インスタンスで同じ ETag を配信するか、ETag を無効にする必要があります。

この状態を確認するには、curl を繰り返し実行して ETag 値の変化を観察します。

curl -s -D - -o /dev/null http://example.com/image.png

出力:

HTTP/2 200
date: Fri, 20 Mar 2020 15:02:30 GMT
server: Apache
strict-transport-security: max-age=31536000; includeSubDomains
last-modified: Mon, 16 Mar 2020 04:20:59 GMT
etag: "10f-5a0f1256f1402"
accept-ranges: bytes
content-length: 271
cache-control: public, max-age=864000
expires: Mon, 30 Mar 2020 15:02:30 GMT
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
content-type: image/png
via: 1.1 google
alt-svc: clear
curl -s -D - -o /dev/null http://example.com/image.png

出力:

HTTP/2 200
date: Fri, 20 Mar 2020 15:03:11 GMT
server: Apache
strict-transport-security: max-age=31536000; includeSubDomains
last-modified: Mon, 16 Mar 2020 04:18:31 GMT
etag: "10f-5a0f11ca09b7a"
accept-ranges: bytes
content-length: 271
cache-control: public, max-age=864000
expires: Mon, 30 Mar 2020 15:03:11 GMT
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
content-type: image/png
via: 1.1 google
alt-svc: clear

Cloud Storage オブジェクトにアクセスできない

Cloud Storage 内のオブジェクトにアクセスできるようにするには、署名付き URL を設定するか、バケットとそのすべてのオブジェクトに allUsers への公開アクセス権を付与する必要があります。

allUsers アクセス権を付与する場合、次の方法でオブジェクトレベルのアクセスを検証できます。

Console

  1. Google Cloud コンソールで、Cloud Storage ブラウザを開きます。

    Storage ブラウザを開く

  2. バケットをクリックして、[バケットの詳細] ページを表示します。

  3. [公開アクセス] 列で、感嘆符アイコンにカーソルを合わせて、[編集権限] をクリックします。

    バケット内の各プロジェクトについて、以下の権限が設定されていることを確認してください。

    • エンティティ: User
    • 名前: allUsers
    • アクセス権: 読み取り

Cloud Storage のアクセス制御の詳細については、Cloud Storage の Identity and Access Management(IAM)のドキュメントをご覧ください。

署名付き URL の詳細については、署名付き URL の使用をご覧ください。

オブジェクトにアクセスできるのにキャッシュに保存されない場合は、レスポンスがキャッシュに保存されないをご覧ください。

非公開コンテンツがキャッシュに保存されるか、キャッシュに保存されたコンテンツが正しくない

送信元サーバーから非公開または正しくないコンテンツが配信される理由がわかっていて、問題を解決できる場合は、次の手順で Cloud CDN のキャッシュを無効にしてください。

  1. 非公開または正しくないコンテンツが送信元サーバーから返されなくなっていることを確認します。
  2. キャッシュの無効化をリクエストして、キャッシュ済みコンテンツの配信を停止するよう Cloud CDN に指示します。

詳細については、キャッシュ無効化の概要をご覧ください。

Cloud CDN はキャッシュへの保存が可能なコンテンツを含むレスポンスのみをキャッシュに保存し、レスポンスで指定された有効期限までキャッシュからレスポンスを配信します。コンテンツがキャッシュに保存された理由がわからない場合や、問題をすぐに解決できない場合は、問題を把握して修正するまで Cloud CDN を無効にし、修正後に再度有効にすることもできます。キャッシュに保存されるコンテンツと保存期間の詳細については、キャッシュの概要をご覧ください。

キャッシュ ヒット率が低い

パフォーマンスとスケーラビリティを向上させるには、キャッシュ ヒット率を最適化することが重要です。キャッシュ ヒット率が想定よりも低い場合は、ベスト プラクティスに沿ってキャッシュ ヒット率を最適化してください。

次の表を使用して、キャッシュ ヒット率が低い理由と可能な修正理由を確認してください。

理由 コメント 解決済みの問題
コンテンツをキャッシュに保存できない キャッシュに保存可能なレスポンスとは、Cloud CDN が保存できる HTTP レスポンスのことです。 コンテンツがキャッシュ可能であることを確認します。
キャッシュ モードは、アプリケーションに対して最適ではありません。 Cloud CDN には複数のキャッシュ モードがあります。 キャッシュ制御ヘッダーを使用してキャッシュ動作を制御していない場合は、Cloud CDN がすべての静的コンテンツをキャッシュに保存できるようにすることをおすすめします。
トラフィック量が少ない。 テスト中には、トラフィックの量が少なくなる可能性があります。Google にはグローバル分散キャッシュがあり、さまざまな地理的位置からのリクエストが異なる Google フロントエンドの場所に送信されます。各フロントエンドのロケーションには、キャッシュの個別のインスタンスが複数存在する可能性があります。
  • 関連するすべてのキャッシュにデータが書き込まれるように、十分な量のトラフィックが Google に送信されていることを確認します。
  • テスト中は、リクエスト セットのすべてのトラフィックが Google に送信されるように、トラフィックを URL ごとにシャーディングしてください。各リクエストを異なる CDN プロバイダにランダムにシャーディングしないでください。
特定の URL のレスポンスがキャッシュに保存されない。 Cloud CDN は完全なリクエスト URI をキャッシュキーに組み込みます。したがって、http://example.com/cat.jpg?color=orangehttp://example.com/cat.jpg?color=gray は別のキャッシュ エントリになります。 特定のリソースに対して常に 1 つの URL を使用します。

キャッシュ可能なページで実行されている JavaScript にパラメータを渡す必要がある場合は、クエリ文字列ではなくフラグメント識別子の使用を検討してください。

Vary ヘッダー フィールドにより、キャッシュが不必要にシャーディングされている。 レスポンスの Vary ヘッダー フィールドは、レスポンスを選択して表す配信元サーバーのプロセスに影響する可能性があるリクエスト メッセージの部分(メソッド、Host ヘッダー フィールド、リクエスト ターゲット以外)を示します。たとえば、圧縮されたレスポンスを処理できるクライアントと処理できないクライアントに異なるコンテンツを配信する場合は、Vary: Accept-Encoding ヘッダーを使用できます。 Vary レスポンス ヘッダーは必要な場合にのみ使用します。
カスタム キャッシュキーを使用していない。 デフォルトの場合、Cloud CDN は完全なリクエスト URL を使用してキャッシュキーを構築します。キャッシュキーをカスタマイズして、プロトコル、ホスト、クエリ文字列の任意の組み合わせの追加や省略を行うことができます。たとえば、2 つのドメインが同じ静的コンテンツを使用している場合は、ホスト フィールドを省略したカスタム キャッシュキーを作成できます。 必要に応じて、カスタム キャッシュキーを使用します。

同じコンテンツに対して複数回キャッシュ フィルが行われる

通常、キャッシュ可能なレスポンスの有効期間を長くすると、キャッシュ フィルの回数を減らすことができます。他の条件がすべて同じ場合、Cache-Control: public, max-age=1 よりも Cache-Control: public, max-age=86400 のレスポンスのほうがキャッシュ フィルが少なくなります。

有効期間の詳細については、有効期間と検証リクエストをご覧ください。適切なレスポンス ヘッダーの設定については、ウェブサーバー ソフトウェアのドキュメントをご覧ください。

Cloud CDN は世界各地で多くのキャッシュを運用しています。新しいコンテンツを保存するため、古いキャッシュ エントリは定期的に削除されています。このため、通常のオペレーションでリソースごとに複数のキャッシュ フィルが存在していることもあります。

圧縮が機能しない

Cloud CDN は、レスポンスを圧縮できない送信元に対して動的圧縮を提供しています。可能であれば、送信元で圧縮することをおすすめします。これにより、キャッシュ フィル料金が削減されます。

Cloud CDN から配信されるレスポンスが圧縮されるはずであるのに圧縮されていない場合は、インスタンス上で稼働しているウェブサーバー ソフトウェアがレスポンスを圧縮するように構成されていることを確認してください。デフォルトでは、一部のウェブサーバー ソフトウェアは、Via ヘッダーを含むリクエストの圧縮を自動的に無効にします。Via ヘッダーが存在する場合は、そのリクエストがプロキシによって転送されたことを示します。外部アプリケーション ロードバランサなどの HTTP プロキシは、HTTP 仕様の要件に従って Via ヘッダーを各リクエストに追加します。圧縮を有効にするには、必要に応じてウェブサーバーのデフォルトの構成をオーバーライドし、リクエストに Via ヘッダーがある場合でもレスポンスを圧縮するように設定します。

nginx ウェブサーバー ソフトウェアを使用している場合は、nginx.conf 構成ファイルを変更して圧縮を有効にします。このファイルの場所は、nginx をインストールした場所によって異なります。多くの Linux ディストリビューションでは、このファイルは /etc/nginx/nginx.conf に保存されています。

nginx 圧縮を外部アプリケーション ロードバランサで機能するように、nginx.conf の http セクションに次の 2 行を追加します。

gzip_proxied any;
gzip_vary on;
  • 最初の行により、外部アプリケーション ロードバランサなどのプロキシから転送されたリクエストでも圧縮が有効になります。

  • 2 番目の行により、レスポンスに Vary: Accept-Encoding ヘッダーが追加されます。Vary: Accept-Encoding は、圧縮可能なリソースの圧縮バリアントと非圧縮バリアントに別々のキャッシュ エントリを維持するように、Cloud CDN などのキャッシュ プロキシに通知します。

nginx.conf を変更した後で新しい構成を使用するには、nginx を再起動する必要があります。多くの Linux ディストリビューションでは、sudo service nginx restart または /etc/init.d/nginx restart を実行して nginx を再起動できます。

レスポンスが byte_range_caching_aborted エラーで終了する

Cloud CDN は、複数のバイト範囲リクエストからレスポンスを作成するときに、ETag リクエスト ヘッダーと Last-Modified リクエスト ヘッダーを比較して、それらの範囲がリソースの同じバージョンからのものかどうかを確認します。Cloud CDN は、いずれかのヘッダーの値がすでにクライアントに提供されている範囲と一致しないことを検出すると、レスポンスを中断します。

レスポンスが予期せず終了した場合、Cloud Logging ログエントリbyte_range_caching_aborted statusDetails が含まれる場合、412 Precondition Failed レスポンスを返すインスタンスがある場合は、すべての仮想マシン(VM)インスタンスで実行されているウェブサーバー ソフトウェアが、特定のリソースに関して同じ ETag 値と Last-Modified 値を返しているかを確認します。

ディスクからファイルを配信する場合、通常、ウェブサーバー ソフトウェアはファイルの変更時刻から ETag 値と Last-Modified 値を取得します。この場合は、すべてのインスタンスで同じイメージを使用することで、VM インスタンスが一貫した値を報告するようにできます。ウェブサーバー ソフトウェアが ETag 値と Last-Modified 値を決定する仕組みについては、ウェブサーバー ソフトウェアのドキュメントをご覧ください。

署名付き Cookie のトラブルシューティング

署名付き Cookie を使用しているときに、次の問題が発生することがあります。

エンコード

署名を生成する際に、署名の不一致が原因でリクエストが予期せず拒否されることがあります。

URL 値と Signature 値をエンコードするときは、base64 の URL セーフなバリアントを使用してください。生成された文字が URL セーフでない場合、標準の base64 は失敗します。パディングは許可されます。

署名

リクエストが Cloud CDN によって拒否されることがあります。

  • 署名アルゴリズムとして HMAC-SHA-1 を使用していること、HMAC の別のバリアントを使用していないことを確認します。

  • (大文字と小文字が区別される)KeyName パラメータが、Cloud CDN で使用されているバックエンド サービスまたはバックエンド バケットの有効なキー名と一致することを確認します。

  • URLPrefix を生成して署名を付ける際には、クエリ パラメータに署名を付けないでください。URLPrefix には、URL のスキーム、ホスト、(部分的な)パスのコンポーネントだけが含まれるようにします。

  • 署名ブロック(URLPrefixExpiresKeyName と、Signature 自体)が、: で区切られた、Cookie の最後のセクションであることを確認します。

  • URLPrefixExpiresKeyNameSignature がこの順序で出現していることを確認します。

  • 署名付き Cookie の URLPrefix の末尾にアスタリスク(*)を使用しないください。

Cookie

  • 通常、ブラウザでは Cookie にドメインあたり 4 KB のサイズ上限と、合計数 50 の上限が適用されています。多くのウェブサーバーではリクエスト ヘッダーにも上限を設けているので、発行してクライアントから送信させる他の Cookie に注意してください。

  • 署名付き Cookie の名前付きパラメータの区切り文字には、アンパサンド(&)文字ではなく、コロン文字(:)(Unicode コードポイント U+003A)を使用してください。

  • 発行する Cookie の Expires タイムスタンプが不必要に短くならないようにしてください。有効期間が 1~2 分に満たないと、発行元アプリと Cloud CDN のインフラストラクチャの間でクロックがずれる問題が発生する可能性があります。

  • 複数の Cookie で同じ DomainPath に異なる値を設定しないでください。ユーザーごとに 1 つの Cookie を設定します。その際、ユーザーがアクセスする必要があるすべてのコンテンツを網羅する URL 接頭辞の値を使用してください。

エラー メッセージ

キャッシュ無効化エラー

エラーコード
Invalid value for field 'resource.path'

パス値の形式が無効です。パスは / で始まる必要があり、?# を含めることはできません。また、* を 1 つだけ含めることができ、これは / の後に続く最後の文字である必要があります。

パスは 1,024 文字以下にする必要があります。このエラーが発生した場合は、パスの値を確認して、形式の誤りを修正してください。

このエラーが示しているのはパスの形式のみです。形式が有効であれば、存在しないパスも有効とされます。

Rate Limit Exceeded Cloud CDN では、キャッシュ無効化オペレーションの実行頻度に制限が設けられています。1 分間に実行できる無効化オペレーションは 1 回だけです。ただし、1 回のオペレーションで、任意の数のオブジェクトに一致するパスパターンを指定できます。

既知の問題

  • キャッシュの無効化に制限があります。1 分間に 1 つの URL マップに実行できる無効化は 1 回だけです。

    解決策: 少なくとも 1 分間待ってから、別の URL マップを無効にしてください。

    キャッシュ無効化のレート制限の詳細については、制限事項をご覧ください。