【玩轉騰訊雲】利用Serverless,實現COS&CDN Combo Handler

什麼是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 這我們需要的內容,記住它。

部署Serverless framework

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

Test1:

請求 https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com/<path1>

這種用法即沒有啟用 combo 功能,serverless server直接返回302 cos url。

不啟用combo

Test2:

請求 https://service-xxxxxx-1250000000.gz.apigw.tencentcs.com??<path1>&<path2>&…

其中,使用 ?? 開啟combo的功能 發現返回回來的文件是兩個文件合併之後的結果,說明這個服務一切正常

啟用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