排解 Cloud CDN 問題

瞭解實用的疑難排解步驟,協助您解決 Cloud CDN 使用過程中遇到的以下問題。

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

一般問題和解決方法

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

系統並未快取回應

如果系統未快取回應,請先檢查您的後端服務或後端 bucket 是否已啟用 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 秒前建立的快取項目,成功從快取提供回應。

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

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

控制台

  1. 在 Google Cloud 控制台中開啟「Cloud Storage browser」(Cloud Storage 瀏覽器)

    開啟「Storage browser」(Storage 瀏覽器)

  2. 點選一個 bucket,查看「Bucket details」(bucket 詳細資料) 頁面。

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

    請務必為 bucket 中的每個物件設定下列權限:

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

如要進一步瞭解 Cloud Storage 的存取控管機制,請參閱 Cloud Storage 的 Identity and Access Management (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 是在原本可快取的頁面上執行,當需要將參數傳送給該 JavaScript 時,建議使用片段 ID 而非查詢字串

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

相同內容存在多個快取填補項目

一般來說,延後可快取回應的到期時間,就能減少快取填補項目數。其他條件相同的情況下,比起包含 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,總數上限則為 50 個。請留意您簽發和要求用戶端傳送的其他 Cookie,因為許多網路伺服器也對要求標頭設有上限。

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

  • 確認您所簽發 Cookie 的 Expires 時間戳記沒有過短。如果有效期限少於一至兩分鐘,簽發端應用程式和 Cloud CDN 基礎架構之間可能會容易發生時鐘偏差問題。

  • 請勿為 DomainPath 相同的多個 Cookie 設定不同值。請為每位使用者設定單一 Cookie,且網址前置字元值應涵蓋使用者需存取的所有內容。

錯誤訊息

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

快取撤銷錯誤

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

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

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

此錯誤碼只代表路徑格式錯誤,如果路徑格式有效但路徑不存在,系統仍會視為有效路徑。

Rate Limit Exceeded Cloud CDN 會限制可執行快取撤銷作業的頻率,每分鐘只允許撤銷一次,但每項作業都可以指定符合任意物件數量的路徑模式。

已知問題

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

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

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