作者:烨爍
CDN 加速 OSS 是常見的站點動靜分離的方式,可以實作将靜态資源存儲在 OSS 上,并通過 CDN 加速 OSS 實作靜态資源的通路加速效果。但是在實際使用的過程中可能會出現使用方法以及配置上的問題導緻使用上出現難題。本文檔主要就 CDN 加速 OSS 的配置以及各注意事項進行描述已解決本使用場景中遇到的問題。
- 使用場景描述
圖 1 所示即是常見的站點動靜分離的解決方案。從該圖中可以檢視到整個站點資料包括動态資源和靜态資源兩個部分,其中動态資源主要是指站點的 web 程式以及資料庫等内容,其主要部署在雲伺服器 ECS 上(資料庫可部署在 RDS 上)。該部分控制了整個站點的業務邏輯,使用者會發動态請求到業務伺服器,業務伺服器決定了系統邏輯傳回給客戶以什麼動态資料。而另外一部分則是以靜态腳本(例如 css 、 js 檔案等)、圖檔、音視訊等靜态資源。這些靜态資源存儲在 OSS 中,然後通過 CDN 對這些靜态資源的下載下傳操作進行加速。而維護 OSS 中的資料則可以通過 ECS 内網操作 OSS 以進行增删改操作。
圖 1. 動靜分離架構示意圖
這樣設計的優勢在于:
- 靜态資源的通路将直接通過 CDN 的邏輯直接傳回給用戶端,而不需要占用 ECS 的各項負載(主要包括帶寬、 CPU 以及記憶體等)。同時靜态資源的上傳也可以通過用戶端直接上傳至 OSS ,避免再經過ECS 。
- CDN 和 OSS 本身提供的下行帶寬非常的高( OSS 限制 5Gbps ,而 CDN 不限制)。是以 ECS 僅需要保證動态資料所占用的帶寬資源即可(一般動态資源占用的下行帶寬相比于靜态資源較少),可以節省ECS 的帶寬規格,節約成本。
-
同一資料中心的 ECS 和 OSS 之間是可以直接通過阿裡雲的内網進行資料互動的,是以可以保證 ECS 和
OSS 的網絡品質。
- CDN 提供了靠近用戶端的節點緩存靜态資源,是以在通路靜态資源時會優先在 CDN 節點中擷取以減少網絡傳輸距離。保證了靜态資源的服務品質。同時 CDN 本身提供全球節點加速,可以一定程度的緩解營運商的國際鍊路對通路帶來的影響。
- 常見問題及解決方案
CDN 加速 OSS 的配置方法可以參考
通過 CDN 加速 OSS Bucket,但是經常有使用者配置完成後發現使用異常的情況,大緻可以分為以下三類。接下來我們較長的描述:
解析未生效。
問題1:域名解析異常。
在 CDN 加速 OSS 的場景中當 CDN 和 OSS 都配置完成後将分别得到 CNAME 域名, CDN 本身有加速域名對應的 CNAME 域名,而OSS 有本身的域名。這裡生效時需要使用者設定該域名的 CNAME 解析到 CDN 的 CNAME 域名上方可生效。例如圖 2 中即是 CDN 加速域名及其對應的 CNAME 域名,使用者在配置完成 DNS 解析後可以通過圖 3 的方式驗證測試。
圖 2. CDN 的 CNAME 域名示意圖
圖 3. dig指令檢測解析是否生效示意圖
問題 2 :域名選擇錯誤。
使用 CDN 加速 OSS 的場景是肯定需要使用者提供一個域名解析到 CDN 上方可提供服務。而這裡常有客戶選擇自己域名的主域名或者www子域名等已經使用的域名添加到 CDN 和 OSS 上。
由于域名本身限制一個主機記錄僅能夠配置一個 A 記錄或者 CNAME 記錄,是以如果該域名已經解析到您的伺服器上的話請不要将該域名再添加在 CDN 和 OSS 上。特别需要注意的是如圖 4 中的“自動添加CNAME 記錄”的操作将會直接在雲解析中添加 CNAME 記錄,是以如果該域名有其他的用途可能會導緻通路異常。
圖 4. 自動添加解析記錄示意圖
通路異常。
問題 1 :回源 host 未綁定在 OSS 的域名管理
CDN 的回源設定包括:回源位址(可以設定為 IP 或者域名)、回源端口和回源 Host 幾個參數。由于 OSS 是沒有提供固定 IP ,而是通過 OSS 域名提供服務的,是以 CDN 回源 OSS 時回源位址寫 OSS 的公網域名即可(注意:CDN 回源都是通過公網回源的,是以這裡隻能夠填寫 OSS 的公網域名,不可以使用 OSS 的内網位址)。而回源端口則可以選擇 80 或者 443 分别代表了 http 協定回源和 https 協定回源的兩種方式。而回源 Host 參數表示了 CDN 請求回到源站時HTTP 的 Request 頭中的 Host 字段的值。
該 Host 字段指代了源站伺服器上具體是哪個應用 server 提供服務的,在 OSS 的場景中由于同一區域的 OSS 是由提供一組前端機提供服務,是以前端機是需要根據 Host 字段識别具體通路的是哪個bucket 中的資料。
在 CDN 加速 OSS 的場景中的回源 Host 設定方法一般有兩種:設定回源 Host 為 OSS 本身的域名和設定為加速域名。如果設定為 OSS 本身的域名當然 OSS 前端機是可以識别為通路的哪個 Bucket ;而如果設定加速域名那麼是需要将該域名綁定在該 Bucket 的自定義域名中,如圖 5 中所示的 wqvod.pier39.cn 這個加速域名回源 Host 為加速域名時時需要在Bucket中綁定該域名不能才可以正常通路的。
圖 5. 回源Host示意圖
問題 2 :OSS 預設首頁不生效
OSS 可以配置靜态托管功能,可以配置預設首頁和 404 頁面。預設首頁即使通過 Bucket 的根目錄即可直接通路設定的預設首頁 html 。例如如下圖的配置,當通路 “
http://dongchics.oss-cn-hangzhou.aliyuncs.com/” 時就會顯示 “
http://dongchics.oss-cn-hangzhou.aliyuncs.com/1.html” 的内容提供服務。
圖 6. 預設首頁設定示意圖
但是當添加 CDN 加速 OSS 後并且在 CDN 上配置“私有 Bucket 回源”功能後會發現通過 CDN 加速域名的根目錄通路無法擷取得到 OSS的預設首頁,而通路得到的是如下圖所示的一個 XML 檔案。從該檔案的内容上可以檢視到傳回的内容是 OSS 調用 listObjects 傳回的結果,其原因就是當開啟“私有 Bucket 回源”後, CDN 通路 OSS 的URL 就會是簽名 URL ,而帶有簽名參數的 URL 通路 OSS 的根目錄是不會執行預設首頁跳轉邏輯的,而是直接調用了 listObjects 并顯示傳回如圖7中的結果,是以該問題的處理方案即使關閉“私有 Bucket 回源”即可。
圖 7. 預設首頁未生效示意圖
問題 3 :CDN 導緻 OSS 檔案大小變化
OSS 通過 putObject 等上傳方式都是會在 response 頭中記錄content-length 和 content-MD5 的資訊傳回給用戶端,如圖8所示。使用者可以根據該資訊确定本地下載下傳得到的檔案是否與 OSS 伺服器端存儲的資料是否一緻。
圖 8. Response頭資訊示意圖
但是當客戶使用 CDN 加速 OSS 後驗證本地的資料有時會發現本地下載下傳的檔案與 OSS 上存儲的檔案的 content-length 或者 content-MD5不一緻。出現該情況有以下原因:
- 擷取 CDN 上的曆史緩存。由于 OSS 上的檔案更新而 CDN 上仍然緩存着曆史的舊資料導緻的該問題,可以通過重新整理 CDN 緩存解決。
- CDN 的智能壓縮功能。 CDN 會對滿足特定條件的檔案自動做 gzip壓縮,當用戶端發送的 Request 頭有 Accept-Encoding : gzip ,即表示用戶端支援 gzip 壓縮并且滿足 CDN智能壓縮 就會進行壓縮,而壓縮後就會導緻該檔案更改為 chunked 編碼,将無法擷取得到 content-length 。
- CDN 的頁面優化功能。 CDN 針對于 html 檔案提供了 trim 的功能,即 CDN 在開啟頁面優化功能後可以幫助使用者自動去掉 html 頁面中的空格以及注釋,這樣可以減少下行流量。但是這就會導緻用戶端接收到的 content-length 或者 content-MD5 發生變化。
- HTTP 劫持問題。當如果用戶端到 CDN 的 L1 節點或者 CDN 的 L2 節點回源到源站使用 HTTP 協定時資料傳輸是非加密的,是以是有可能出現在網絡傳輸的過程中包内容被篡改的情況。這種情況就會導緻用戶端接收與 OSS 存儲内容不一緻。該問題可以通過修改為 HTTPS 協定規避該問題。
問題 4 :CDN 回源到老版本圖檔處理域名
OSS 預設提供的是“oss-cn-.aliyuncs.com”的域名提供服務,但是針對于老版本的圖檔處理仍然提供了“img-cn-.aliyuncs.com”供老版本的圖檔處理樣式方式通路(通過@!樣式名或者@樣式處理串)。但是相比于 OSS 本身的域名,圖檔處理域名是不提供 HTTPS 協定的,是以在 CDN 上回源到 OSS 圖檔處理域名是不可以設定回源到 443 端口的,同時是不可以開啟協定跟随回源功能的,否則将會導緻 HTTPS 協定通路出現異常的情況。
問題 5 :CDN 加速後 OSS 的 CORS 配置未生效
當出現來自不同的域的 JavaScript 動态請求其他域的靜态資源時會觸發浏覽器的跨域請求,而這時浏覽器會在 HTTP 的 Request 頭中添加Origin 頭表示是由哪個域通路該資源的。而 OSS 作為靜态資源存儲産品是允許設定 CORS 頭設定允許哪些域進行跨域通路的。詳細的設定請參考
OSS 的 CORS 設定。
OSS 當接收到用戶端的 Request 頭中帶有 Origin 頭并且與 CORS 配置比對的話那麼會在 Response 頭中 Access-Control-Allow-Origin等頭資訊表示允許跨域通路。但如果 Request 頭沒有 CORS 頭的話那麼 OSS 是不會傳回 Access-Control-Allow-Origin 等頭資訊。這種情況在使用 CDN 加速 OSS 的時候就會導緻如果曆史有沒有跨域請求OSS 的傳回資訊緩存在 CDN 節點上,下次通路觸發跨域時直接擷取緩存資料導緻鑒權不通過的。
該問題最好的解決方案就是在 CDN 上配置 CORS 頭,這樣保證不管用戶端是否有觸發跨域請求都會在 Response 帶有 Access-Control-Allow-Origin 等頭資訊的。避免由于曆史的未觸發 CORS 的緩存資料影響真正的跨域請求,具體的設定請參考
CDN配置CORS頭問題 6 :過濾參數導緻回源請求缺失
OSS 的權限包括公共讀寫、公共讀和私有三種權限,對公共讀的Bucket 執行寫操作核對私有的 Bucket 執行讀和寫的操作時都是需要通路的時候加上身份驗證的簽名參數的。這裡以讀為例,以 URL 的方式讀取 OSS 的資源時是需要加上 OSSAccessKeyId 、 Expires 和Signature 三個參數的 queryString 的參數才可以正常通路的,如果沒有添加這些參數就會報“403 Access Denied”的錯誤。
而 CDN 上是提供了過濾參數的功能是指當 CDN 收到請求 URL 後去除掉 URL 中的 querystring 檢視是否有緩存檔案命中,如果沒有的話就會使用沒有 querystring 的 URL 回源拉取資源。例如:由于 CDN加速 OSS 的通路URL是“
http://wqtest.test.com/1.jpg?Expires=1511700494&OSSAccessKeyId=TMP.AQGmSnv_MDL_qdYESUo2KTjtyS5aqHdRVF8Cjko_zeyEC4rwnnOWyTVfoBAHMC4CFQDa1RE0F6h3Z1s0RV3OyZfdL1jmFgIVAM2ENr7Ae5c1LqDyi3LO2ba4seyk&Signature=NS8xhKGyyHEzzIK4CmqaxzCcfwo%3D”,其中 wqtest.test.com 是開啟了過濾參數的 CDN 加速域名。那麼CDN 節點在受到該請求後會将該 URL 改寫成“
http://wqtest.test.com/1.jpg”,然後依次檢視 CDN 的 L1 節點和L2 節點上是否有緩存資料,如果有的話就直接将該緩存資料回報給用戶端,否則就會回源到 OSS 。而這時 OSS 如果是私有的話接收到該請求将無法正常通路就會抛出 403 Access Denied 的錯誤。
這裡最直接的處理辦法就是關閉過濾參數功能,這樣回源的時候就會帶上完整的 querystring 。但是這樣設定同樣會帶來一個問題就是當queryString 中的參數發生更改後那麼 CDN 會認為是完全不同的 URL重新緩存,是以這種情況下可能會導緻 CDN 緩存命中率下降。其他的解決方案建議參考後面的“問題 7 :私有 Bucket 回源和鑒權功能的設定”。
問題 7 :私有 Bucket 回源和鑒權功能的設定
在問題 6 中我們介紹了當 OSS 設定為私有時不可以開啟過濾參數并且當簽名 querystring 發生變化時還會影響 CDN 緩存命中率。該問題的解決方案就是 CDN 開啟私有 Bucket 回源。
該功能将使 CDN 的請求回源 OSS 的時候自動帶上簽名 querystring參數,而不需要客戶自己在請求 CDN 的時候設定。這樣即實作了 OSS 本身資源的安全防護而又不影響 CDN 的緩存命中率。
同時如果客戶需要對 CDN 的請求也要求鑒權的話可以在 CDN 上配置鑒權功能,同時鑒權參數發生更改是不影響緩存命中率的。
重新整理問題。
CDN 加速 OSS 的場景提供了 OSS 源檔案更新後提供自動重新整理 CDN緩存的功能,該功能是在 OSS 控制台的域名管理頁面中開啟,如圖 9所示。開啟該功能是需要該域名同時在 CDN 和 OSS 上綁定才可以正常使用,否則就很按照圖 8 中的第一條記錄無法開啟該功能。
圖 9. CDN 緩存自動重新整理示意圖