記錄MVC專案部署時的CDN快取問題

記得要微笑發表於2021-12-06

概述

本文將分析在釋出前後端未分離專案(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連結打上的是新版本號。

部署後html中不是最新的版本號.png

解決方案:待專案部署完成後重新整理頁面就可以了

2、script指令碼連結是新版本號但拉取到的卻是舊指令碼程式碼

正常來說,部署專案後,瀏覽器根據新版本號去請求CDN上的靜態指令碼檔案,如果CDN快取中沒有對應新版本號對應的指令碼檔案,則會向後端服務拉取新指令碼,然後CDN在做一次快取,後面的指令碼請求直接由CDN返回。

但是,如果部署還未完成瀏覽器就去訪問了,此時這個階段新服務和舊服務是同時存在的,當新版本號對應的指令碼在CDN上找不到時,就會去服務請求,恰恰請求命中的是舊服務(服務響應跟版本號無關),舊服務返回舊的指令碼,然後CDN快取新版號對應的舊指令碼,這樣後續每次請求拉取到的都是CDN上快取的就指令碼,因此就出現了上述問題。

新版本號未拉取到新指令碼.png

解決方案:重新部署一遍,待部署完成後再去訪問頁面

相關文章