【玩轉騰訊雲】利用Serverless,實現COS&CDN Combo Handler
- 2020 年 4 月 8 日
- 筆記
什麼是Combo Handler ?相信很多前端同學並不陌生。2008年7月YUI Team宣布在YAHOO! CDN上對YUI JavaScript組件提供Combo Handler服務。簡單講,當前端有n個 js 需要分別去拉取時,通過 cdn combo 技術能用一個請求把 js 在服務端合併後拉回,同理可用於 css 文件。
背景:
小S維護的一個前端系統,單個頁面中有數個沒有依賴關係的 js 、css 需要加載,此時瀏覽器會分別去請求對應的文件。此時小S收到Leader給的一個任務:優化前端的靜態資源請求,盡量做合併。
現狀:
小S馬上開始着手,看了下手頭的項目,目前靜態資源是經過 騰訊雲CDN 的,靜態資源放在了 騰訊雲COS對象存儲,js、css文件因為模塊的不同,被打包成了多個。而騰訊雲 CDN 目前不支持 Combo 的方式。
分析:
小S開始想到了HTTP2.0,但看了CDN的請求配置已開啟HTTP2.0,這一塊能提升的空間已不大。那是否能做靜態的離線合併處理,看似可行的一條路,但改動量不小,且確實涉及到一些歷史原因,這塊不好動。小S突然想起以前了解過的CDN Combo,那從請求實時合併入手,也是可行的。但可惜,目前接入的CDN沒能支持。
此時天空飄來一句道格拉斯·熙凝的話打在了小S身上
淡黃的長…不是,計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決
目前靜態資源的請求鏈路是 前端 → CDN → COS,想做實時合併的話,那可以在CDN和COS之間加入一個中間層來實現,這個中間層根據過來的請求,分別去COS上拉取文件做合併後返回給CDN,CDN則可以根據請求的路徑做緩存。而適合做這個中間層的,小S首先想到了最近火的不行的 Serverless。
小S如夢初醒,甚是感動,簡單手動幾下便完成了。下面來把實現過程中的關鍵步驟分享出來。
實現:
原理:
使用Serverless framework實現一個server,用來給cdn作為源站,server中根據cdn過來的判斷是否開啟combo特性,這裡使用url中的 ?? 雙問號開啟combo特性,使用 & 連接多個文件路徑,如 xxx.com??<pathA>&<pathB>。如果啟用,則去COS上拉取對應的文件合併後返回。如果不啟用,則跟原始請求單個文件一樣,如 xxx.com/<pathA> ,則server返回302 cos鏈接到cdn,讓cdn去follow 302,與原始使用沒有差別。
涉及相關產品
- 1、安裝Serverless framework命令行工具
// 非npm安裝可查看 https://cloud.tencent.com/document/product/1154/42990 npm install -g serverless serverless -v
- 2、修改 demo 配置
下載這個 cdn-combo demo的代碼,解壓後得到cdn-combo文件夾,修改裏面的幾個配置信息,包括SecretId、SecretKey、Bucket以及Region。
其中,Bucket、Region即原本CDN回源的COS源站的桶信息,如果修改了app.js中的Region,也要同時修改serverless.yml中的region的值,這樣保證了Serverless服務請求COS時走的是騰訊內網。
SecretId、SecretKey即賬號的密鑰信息。
(該例子是從一個存儲桶中拿不同文件進行合併,如何希望從不同存儲桶,乃至從非COS的源站中拿文件進行合併,均可自行參考實現)

- 3、Serverless部署
在cdn-combo文件夾下執行進行serverless的部署
sls --debug
部署過程中需要掃描二維碼進行登錄,如果希望持久化登錄狀態,可參考 文檔
部署完成,在命令行我們會得到如下信息,此時證明中間服務已部署起來,拿到url的host部分 https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com 這我們需要的內容,記住它。

接下來簡單測試下是否能正常工作,在COS源站中有如下兩個文件

Test1:
請求 https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com/<path1>
這種用法即沒有啟用 combo 功能,serverless server直接返回302 cos url。

Test2:
請求 https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com??<path1>&<path2>&…
其中,使用 ?? 開啟combo的功能 發現返回回來的文件是兩個文件合併之後的結果,說明這個服務一切正常

- 4、設置CDN回源Serverless Server Url
登錄CDN控制台,找到之前接入的域名,或者接入個新的域名。
以下面作為例子,cdn域名為 cdn-combo.galen-yip.com,修改源站,源站選擇自有源,回源協議務必選擇HTTP
,源站地址以及回源 host 填寫 Serverless server url,待設置成功,至此我們變完成了所有的變更工作。

- 5、驗收成果
訪問 http://cdn-combo.galen-yip.com/js-combo/foo.js 返回200 以及單文件內容
訪問 http://cdn-combo.galen-yip.com/??js-combo/foo.js&js-combo/bin.js 返回200 以及文件合併後的內容
最後把頁面 http://cdn-combo-demo-1251496585.cos.ap-guangzhou.myqcloud.com/index.html
中的靜態資源引用,改變成以上 cdn combo 的引用方式
結語:
以上便完成了CDN Combo Handler 能力。特別注意,CDN源站從COS改為Serverless server,計費這邊是有變更的,具體可以查詢對應產品的流量計費情況。
Serverless能發揮的作用遠不止此,如果有更多玩法,私我。
最後附上demo下載地址:https://galenye-1251496585.cos.ap-guangzhou.myqcloud.com/cdn-combo.zip