概述
本文將分析在釋出前後端未分離專案(freemaker
)時遇到的CDN
快取問題,主要有以下兩個問題:
- 頁面請求獲取的
html
裡面卻是舊版本號的script
連結 script
指令碼連結是新版本號但拉取到的卻是舊指令碼程式碼
問題分析
1、頁面請求獲取的html
裡面卻是舊版本號的script
連結
問題分析前首先我們要知道以下知識點:
(1)freemaker
專案的頁面是後端服務將ftl
處理成html
返回的
(2)部署時會遍歷ftl
檔案,對所有的script
連結打上版本號
// 構建前 supplierQuoteDetailPaging.ftl
<!DOCTYPE html>
<head>
<script type="text/javascript" src="${Global.getConfig("web.app.static.url")}/js/supplierQuoteDetail.js"></script>
</head>
</html>
// 在`Jenkins`構建後會對請求靜態指令碼的`url`加上版本號 supplierQuoteDetailPaging.ftl
<!DOCTYPE html>
<head>
<script type="text/javascript" src="${Global.getConfig("web.app.static.url")}/js/supplierQuoteDetail.js?version=1638706227856"></script>
</head>
</html>
(3)後端是叢集服務,部署採用滾動釋出,也就是說部署時節點服務是一批一批來更新的,直到叢集中所有的例項都更新成新版本,而不是一次性全量更新
當專案還是部署時,因為服務採用滾動釋出,因此在這個期間新服務和舊服務會同時存在。如果在這個階段訪問頁面,頁面介面可能命中舊服務,也可能命中新服務,當命中舊服務時,請求得到的html
裡面script
連結打上的是舊版本號;當部署完成時,群中所有的例項都更新成新版本,頁面請求命中新服務,請求得到的html
裡面script
連結打上的是新版本號。
解決方案:待專案部署完成後重新整理頁面就可以了
2、script
指令碼連結是新版本號但拉取到的卻是舊指令碼程式碼
正常來說,部署專案後,瀏覽器根據新版本號去請求CDN
上的靜態指令碼檔案,如果CDN
快取中沒有對應新版本號對應的指令碼檔案,則會向後端服務拉取新指令碼,然後CDN
在做一次快取,後面的指令碼請求直接由CDN
返回。
但是,如果部署還未完成瀏覽器就去訪問了,此時這個階段新服務和舊服務是同時存在的,當新版本號對應的指令碼在CDN
上找不到時,就會去服務請求,恰恰請求命中的是舊服務(服務響應跟版本號無關),舊服務返回舊的指令碼,然後CDN
快取新版號對應的舊指令碼,這樣後續每次請求拉取到的都是CDN
上快取的就指令碼,因此就出現了上述問題。
解決方案:重新部署一遍,待部署完成後再去訪問頁面