排解 Cloud CDN 問題

瞭解實用的疑難排解步驟,解決您在使用 Cloud CDN 時遇到的問題。

如果問題與外部後端有關,請參閱「排解外部後端和網際網路 NEG 問題」。

一般問題和解決方案

本節說明一些常見問題和解決方法。

系統沒有快取回應

如果系統未快取回應,請先確認後端服務或後端儲存空間已啟用 Cloud CDN。啟用 Cloud CDN 後,可能需要幾分鐘的時間,系統才會開始快取回應。

Cloud CDN 只會快取可快取內容的回應。這項資訊會透過 HTTP 回應標頭傳達,並搭配後端設定。使用 cdn_cache_status 設定自訂回應標頭後,您可以在 Cloud CDN 記錄中觀察快取狀態,並判斷回應是否因快取未命中而提供。

如果系統未快取網址的回應,請檢查該網址傳回的標頭,以及後端快取功能的設定方式

您可以透過下列幾種方式檢查回應標頭:

以下範例說明如何使用 curl 檢查 HTTP 回應標頭中的 http://example.com/style.css

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 秒前建立的快取項目,成功從快取提供回應。

此外,如果後端執行個體已啟用 ETags,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 中的物件存取權,您必須設定已簽署的網址,或是為 allUsers 授予該值區及其所有物件的公開存取權。

如果您決定要提供 allUsers 存取權,可以按照以下步驟驗證物件層級存取權。

控制台

  1. 在 Google Cloud 控制台中,開啟 Cloud Storage 瀏覽器

    開啟 Storage 瀏覽器

  2. 按一下值區以查看「Bucket details」(值區詳細資料) 頁面。

  3. 在「Public access」(公開存取權) 資料欄中,將指標懸停在驚嘆號圖示上,然後按一下「Edit access」(編輯存取權)。

    請確認您已為值區中的每個物件設定下列權限:

    • 實體:User
    • 名稱:allUsers
    • 存取權:Reader

如要進一步瞭解 Cloud Storage 的存取權控管,請參閱 Cloud Storage 的身分與存取權管理 (IAM) 說明文件

如要進一步瞭解已簽署的網址,請參閱使用已簽署的網址

如果您可以存取物件,但系統未予以快取,請參閱系統沒有快取回應

快取的內容為私人內容,或快取的內容不正確

如果您知道原始伺服器提供私人或不正確內容的原因並能夠修正問題,則可以使用下列程序撤銷 Cloud CDN 快取:

  1. 確保原始伺服器不再傳回私人或不正確的內容。
  2. 要求撤銷快取,指示 Cloud CDN 停止提供快取內容。

詳情請參閱「快取撤銷總覽」。

Cloud CDN 只會快取可快取內容的回應,且只會在回應中指定的有效期限內,從快取提供回應。如果您不知道系統為何快取這項內容,或是無法適當修正問題,可以先停用 Cloud CDN,等到您瞭解並修正問題後,再重新啟用。如要進一步瞭解快取的內容及時間長度,請參閱「快取總覽」。

快取命中率偏低

為了提升效能和擴充性,設法提升快取命中率是很重要的一件事。如果快取命中率低於預期,請務必遵循最佳做法提高快取命中率

請參閱下表,瞭解快取命中率偏低的可能原因和解決方法。

原因 註解 修正項目
您的內容無法快取 可快取的回應是指 Cloud CDN 可以儲存的 HTTP 回應。 請確認內容可快取
快取模式不適合您的應用程式。 Cloud CDN 提供多種快取模式 如果您未使用快取控制標頭來控制快取行為,建議最佳做法是讓 Cloud CDN 快取所有靜態內容。
流量偏低。 在測試和實驗期間,您產生的流量可能偏低。Google 擁有全球分散式快取,來自不同地理位置的要求會傳送至不同的 Google 前端位置。在每個前端位置,Google 可能有多個獨立的快取執行個體。
  • 請確保傳送至 Google 的流量足夠,可填入所有相關快取。
  • 測試期間,請務必依網址將流量分片,確保每組要求的所有流量都會傳送至 Google。請勿隨機將每個要求分片至不同的 CDN 供應商。
特定網址的回應不會快取。 Cloud CDN 會將完整的要求 URI 納入快取金鑰,因此 http://example.com/cat.jpg?color=orangehttp://example.com/cat.jpg?color=gray 會有不同的快取項目。 指定資源一律使用單一網址。

如果您需要將參數傳送給在另一個可快取頁面上執行的 JavaScript,請考慮使用 片段 ID,而非使用查詢字串

由於 Vary 標頭欄位,快取遭到不必要的分片。 回應中的 Vary 標頭欄位會說明要求訊息的哪些部分 (方法、Host 標頭欄位和要求目標除外),可能會影響來源伺服器選取及表示回應的程序。舉例來說,如果您為可處理壓縮回應的用戶端和無法處理壓縮回應的用戶端提供不同內容,可能就會想使用 Vary: Accept-Encoding 標頭。 只在必要時使用 Vary 回應標頭。
您未使用自訂快取金鑰 根據預設,Cloud CDN 會使用完整的要求 URL 建構快取金鑰。您可以自訂快取金鑰,加入或省略任何通訊協定、主機和查詢字串的組合。舉例來說,如果兩個網域使用相同的靜態內容,您可以建立自訂快取金鑰,省略主機欄位。 視需要使用自訂快取金鑰。

相同內容有多個快取填補作業

一般來說,透過增加可快取回應的到期時間,就能降低快取填補數。在其他條件相同的情況下,與 Cache-Control: public, max-age=1 相比,使用 Cache-Control: public, max-age=86400 的回應快取填入次數較少。

如要進一步瞭解到期時間,請參閱「到期時間和驗證要求」。如要瞭解如何設定適當的回應標頭,請參閱網路伺服器軟體的說明文件。

Cloud CDN 在全球各地運作許多快取,並定期移除舊的快取項目,以挪出空間存放新內容。因此,正常運作時,每個資源預期會多次填滿快取。

壓縮無法作用

Cloud CDN 為無法壓縮回應的來源提供動態壓縮功能。建議您盡可能在來源端使用壓縮功能,因為這樣可以降低快取填滿費用。

如果 Cloud CDN 提供的回應沒有壓縮,但應該要壓縮,請檢查在執行個體上執行的網路伺服器軟體是否設為壓縮回應。根據預設,部分網頁伺服器軟體會自動停用包含 Via 標頭的要求壓縮功能。如果存在 Via 標頭,表示要求是由 Proxy 轉送。外部應用程式負載平衡器等 HTTP Proxy,會依據 HTTP 規格在每個要求中新增 Via 標頭。如要啟用壓縮功能,您可能必須覆寫網路伺服器的預設設定,即使要求有 Via 標頭,也要壓縮回應。

如果您使用的是 nginx 網路伺服器軟體,請修改 nginx.conf 設定檔以啟用壓縮功能。這個檔案的位置取決於 nginx 的安裝位置。在許多 Linux 發行版中,該檔案會儲存在 /etc/nginx/nginx.conf

如要讓 nginx 壓縮功能與外部應用程式負載平衡器搭配運作,請在 nginx.conf 的 http 區段中新增下列兩行:

gzip_proxied any;
gzip_vary on;
  • 第一行可啟用壓縮功能,即使是外部應用程式負載平衡器等 Proxy 轉送的要求也適用。

  • 第二行會在回應中加入 Vary: Accept-Encoding 標頭。 Vary: Accept-Encoding 會通知 Cloud CDN 等快取 Proxy,應為可壓縮資源的壓縮和非壓縮變體維護個別的快取項目。

修改 nginx.conf 後,您必須重新啟動 nginx,才能使用新的設定。在許多 Linux 發行版中,您可以執行 sudo service nginx restart/etc/init.d/nginx restart 重新啟動 nginx。

回應因 byte_range_caching_aborted 錯誤而終止

Cloud CDN 從多個位元組範圍要求組裝回應時,會比較 ETagLast-Modified 回應標頭,檢查這些範圍是否來自相同版本的資源。如果 Cloud CDN 發現任一標頭的值與已提供給用戶端的範圍不一致,就會中止回應。

如果發現回應意外終止、Cloud Logging 記錄項目含有 byte_range_caching_aborted statusDetails,或是執行個體傳回 412 Precondition Failed 回應,請確認所有虛擬機器 (VM) 執行個體上執行的網頁伺服器軟體,針對特定資源傳回的 ETagLast-Modified 值相同。

從磁碟提供檔案時,網路伺服器軟體通常會從檔案的修改時間衍生 ETagLast-Modified 值。在這種情況下,您可以為所有執行個體使用相同的映像檔,確保 VM 執行個體回報一致的值。如要進一步瞭解網頁伺服器軟體如何判斷 ETagLast-Modified 值,請參閱網頁伺服器軟體說明文件。

排解已簽署的 Cookie 問題

使用簽章 Cookie 時,可能會發生下列問題。

編碼

產生簽章時,由於簽章不符,要求遭到拒絕。

編碼 URLSignature 值時,請務必使用 Base64 的網址安全變體。如果產生的字元不符合網址安全規定,標準 base64 就會失敗。接受填補。

簽署

Cloud CDN 拒絕了您的要求。

  • 請確認您使用的是 HMAC-SHA-1 簽署演算法,而非其他 HMAC 變體。

  • 確認 (區分大小寫的) KeyName 參數與 Cloud CDN 使用的後端服務或後端 bucket 的有效金鑰名稱相符。

  • 產生及簽署 URLPrefix 時,請勿簽署查詢參數。請確認 URLPrefix 只包含網址的架構、主機和 (部分) 路徑元件。

  • 確認簽章區塊 (URLPrefixExpiresKeyNameSignature 本身) 是 Cookie 中最後以 : 分隔的部分。

  • 請確認 URLPrefixExpiresKeyNameSignature 依序出現。

  • 在已簽署的 Cookie 中,URLPrefix 的結尾不得包含星號 (*) 字元。

Cookie

  • 瀏覽器通常會將每個網域的 Cookie 限制為 4 KB,每個網域的 Cookie 總數則限制為 50 個。請注意您發布並要求用戶端傳送的其他 Cookie,因為許多網頁伺服器也有要求標頭上限。

  • 請務必使用半形冒號 (:) Unicode 代碼點 U+003A,做為已簽署 Cookie 中具名參數的分隔符,而非半形連字號 (&) 字元。

  • 請確保您發行的 Cookie 上的 Expires 時間戳記不會過短。如果效期少於一到兩分鐘,發行應用程式和 Cloud CDN 基礎架構之間可能容易發生時鐘偏差問題。

  • 請確認您未針對相同的 DomainPath 設定多個值不同的 Cookie。為每位使用者設定單一 Cookie,並提供涵蓋使用者需要存取的所有內容的網址前置字元值。

錯誤訊息

本節提供一些常見錯誤訊息的相關資訊,以及解決方法。

快取撤銷錯誤

錯誤代碼 附註
Invalid value for field 'resource.path'

路徑值的格式無效。路徑開頭須為 /,不得包含 ?#,且只能有一個 *,並須為 / 後的最後一個字元。

路徑長度不得超過 1024 個字元。如果收到這則錯誤訊息,請檢查路徑值並修正格式錯誤。

這項錯誤只會影響路徑格式。格式正確但不存在的路徑仍視為有效。

Rate Limit Exceeded Cloud CDN 會限制可以執行快取撤銷作業的頻率。每分鐘最多可提交 500 個失效要求。每個作業都可以指定路徑模式,比對任意數量的物件。

已知問題

  • 快取撤銷的頻率限制為每分鐘每個網址對應只能進行一次撤銷。

    解決方法:請等待至少一分鐘,再嘗試撤銷其他網址對應。

    如要進一步瞭解快取撤銷頻率限制,請參閱「限制」。