在頻繁發(fā)布上線節(jié)奏下如何解決靜態(tài)文件緩存

為了提升網(wǎng)站的訪問速度,需要盡可能的減少客戶端與服務(wù)器端的請求數(shù)量與傳輸?shù)臄?shù)據(jù)量以及服務(wù)器從硬盤或數(shù)據(jù)庫讀取內(nèi)容的頻率汗洒,最常用的解決方法就是引入緩存减牺。當(dāng)然是嗜,雖然緩存在提升性能表現(xiàn)的很好但也不可避免的帶來一些問題解取,比如緩存不同步步责,緩存不及時更新等問題,這篇文章主要總結(jié)緩存對靜態(tài)文件資源進(jìn)行緩存所帶來的問題以及如何解決。

當(dāng)然勺择,解決緩存的辦法很簡單,就是不需要緩存或者每次發(fā)布之后的文件名都改變伦忠,導(dǎo)致上一個版本的緩存失效省核。顯然這并不是我們的目的,我們的目的是前后兩次迭代發(fā)布上線要做到文件名稱隨文件內(nèi)容同步改變昆码,這樣才能在快速迭代發(fā)布上線中實現(xiàn)緩存的最大利用率气忠。

涉及到的緩存實現(xiàn)分客戶端與服務(wù)器端兩種。

  1. 客戶端緩存
    客戶端緩存赋咽,就是把不經(jīng)常變動的文件數(shù)據(jù)緩存在客戶端旧噪,便于下次訪問時直接從本地獲取緩存的文件。要實現(xiàn)本地文件緩存脓匿,需要滿足兩個條件:

    • 服務(wù)器端在請求返回頭部中設(shè)置cache-control或expires等...
    • 需要緩存的文件前后兩次必須同名
  2. 服務(wù)器端緩存
    服務(wù)端緩存就是后端服務(wù)把文件從硬盤中讀取返回給客戶端之后淘钟,把文件內(nèi)容緩存起來,當(dāng)下次客戶端再請求該文件時陪毡,直接從緩存(內(nèi)存米母?)讀取而不需要從硬盤讀取,提升訪問速度與減少服務(wù)器壓力毡琉。然后返回給客戶端并設(shè)置緩存頭部铁瞒,實現(xiàn)客戶端緩存。

設(shè)置緩存頭部很簡單桅滋,而文件名稱與文件內(nèi)容同步改變就涉及到前端打包慧耍,而NEJ打包已經(jīng)實現(xiàn)此功能。

最近剛好遇到這樣的問題丐谋,由于打包方式的問題加上服務(wù)器vanish緩存的存在芍碧,最終在vanish緩存中導(dǎo)致新版本的文件名緩存了舊版本文件的內(nèi)容,導(dǎo)致報錯号俐。為了避免此類問題的再次出現(xiàn)或者出現(xiàn)后方便解決师枣,于是對此次問題做了個總結(jié)。問題的出現(xiàn)涉及到多個步驟 萧落,結(jié)合教育產(chǎn)品部門的通用打包方式與ndp部署方式以及服務(wù)器緩存等方面闡述問題的發(fā)生践美、解決、思考等過程找岖。此次問題的解決感謝各位后端大大的耐心解答陨倡。

1、前端NEJ打包規(guī)則

  1. release.conf配置對打包結(jié)果的影響
    NEJ打包工具配置對靜態(tài)文件的處理常用方式大致有3種:
    • 文件名固定
      如prefix_relative_file_path.js, filename.html (本地许布、測試環(huán)境使用)

    • 固定文件名+?內(nèi)容md5值版本號
      每次打包根據(jù)文件內(nèi)容生成版本信息兴革,版本號通過地址的查詢串?dāng)y帶,如/prefix_relative_file_path.js?65b61c1aabc7a07c9c7525a398b4555a,filename.html?65b61c1aabc7a07c9c7525a398b4555a

    • 固定文件名+md5值.js
      每次打包根據(jù)文件內(nèi)容生成md5值杂曲,把md5值添加在文件名稱中庶艾,如/prefix_relative_file_path_65b61c1aabc7a07c9c7525a398b4555a.js,filename_65b61c1aabc7a07c9c7525a398b4555a.html

教育產(chǎn)品部門前期主要使用的是第二種方式擎勘,期間遇到問題的幾率很小咱揍,現(xiàn)在改成了js使用第三種,而模塊html繼續(xù)使用第二種的方式棚饵,屬于修改不完全的方式煤裙,當(dāng)然也會遇到緩存問題,只是影響范圍從頁面下降到了某一模塊噪漾。所以要完全解決這個問題硼砰,必須js、html都是用第三種方式欣硼。

NEJ以NEJ打包工具也在迭代當(dāng)中题翰,以上的三種打包方式有一定的版本要求
建議: nej >= 0.4.0 、 nej打包工具 >= 1.6.6诈胜。此外還需要在release.conf配置文件中添加一些參數(shù)

###############################################
###############     版本配置    ###############
###############################################
# 靜態(tài)資源是否自動帶版本號
# 靜態(tài)資源即DIR_STATIC配置的目錄下的所有資源文件的引入均自動帶上版本信息
# 忽略自帶版本的靜態(tài)資源路徑遍愿,如url(/path/to/a.png?v=1234)
VERSION_STATIC = true
# 版本號生成規(guī)則,默認(rèn)自動模式
# 0 - 自動模式耘斩,根據(jù)文件內(nèi)容生成沼填,版本號通過地址的查詢串?dāng)y帶,如/a.js?9e107d9d372bb6826bd81d3542a419d6
# 1 - 隨機(jī)模式括授,每次生成隨機(jī)版本信息坞笙,不重復(fù),版本號通過地址的查詢串?dāng)y帶荚虚,如/a.js?123456
# * - 固定模式薛夜,配置字符串作為文件名后綴,地址的查詢串中不再攜帶版本信息版述,
#     如配置為v1,則生成的文件文件名后追加此配置值梯澜,生成文件名如a_v1.js
#     配置中可以使用以下變量來表示內(nèi)建值,如果出現(xiàn)以下變量渴析,則不再追加原文件名
#     [RAND]     - 替代隨機(jī)版本號晚伙,如[FILENAME]_[RAND]則生成文件a_9865734934.js
#     [VERSION]  - 替代文件的MD5值,如v2_[VERSION]則生成文件為v2_9e107d9d372bb6826bd81d3542a419d6.js
#     [FILENAME] - 替代文件名俭茧,系統(tǒng)自動生成的唯一文件名標(biāo)識咆疗,如[FILENAME]_v2則生成文件a_v2.js
VERSION_MODE = [FILENAME]_[VERSION]

#靜態(tài)資源版本號生成規(guī)則,默認(rèn)自動模式母债,配置說明如下:

# 0 - 自動模式午磁,根據(jù)文件內(nèi)容生成尝抖,版本號通過地址的查詢串?dāng)y帶,如/a.png?9e107d9d372bb6826bd81d3542a419d6
# 1 - 隨機(jī)模式迅皇,每次生成隨機(jī)版本信息昧辽,不重復(fù),版本號通過地址的查詢串?dāng)y帶登颓,如/a.png?123456
# * - 固定模式搅荞,配置字符串作為文件名后綴,地址的查詢串中不再攜帶版本信息挺据,如配置為v1,則生成的文件文件名后追加此配置值,生成文件名如a_v1.png
# 固定模式配置中可以使用以下變量來表示內(nèi)建值脖隶,如果出現(xiàn)以下變量扁耐,則不再追加原文件名

# [RAND] - 替代隨機(jī)版本號,如[FILENAME]_[RAND]則生成文件a_9865734934.png
# [VERSION] - 替代文件的MD5值产阱,如v2_[VERSION]則生成文件為v2_9e107d9d372bb6826bd81d3542a419d6.png
# [FILENAME] - 替代文件名婉称,系統(tǒng)自動生成的唯一文件名標(biāo)識,如[FILENAME]_v2則生成文件a_v2.png
VERSION_STATIC_MODE = [FILENAME]_[VERSION]
#模塊文件的版本模式构蹬,支持配置的值如下所示

# 0 - 使用查詢參數(shù)的版本【默認(rèn)配置】王暗,如 index.html?12343423432
# 1 - 使用路徑版本,比如 index.html 的模塊生成 index_13432233243.html 的打包文件
NEJ_MODULE_VERSION = 1

期間由于打包工具更新不同步問題(nej打包工具與工程依賴的NEJ庫)庄敛,導(dǎo)致打包結(jié)果中出現(xiàn)兩種不同的打包結(jié)果俗壹,即模塊名稱引用優(yōu)先順序命名方式與文件路徑md5值命名方式同時存在,就會出現(xiàn)以下問題藻烤,導(dǎo)致文件錯誤緩存問題很容易發(fā)生

// 文件路徑md5值命名方式
EDU("f7e564f950f1972bf97cf95d72460f6f",function(e,t,i,n,r,a,o,s,c,d){var l={},f,u={}})

// 模塊名稱引用優(yōu)先順序命名方式
EDU(23,function(e,t,i){var l={},f,u={}})
  • core.js文件名稱必變
  • 其他js文件是否改變具有不確定性

以上兩點(diǎn)會引起:

  • js的改變導(dǎo)致模塊html文件的內(nèi)容改變(html引用js)
  • 模塊html的改變導(dǎo)致頁面ftl文件內(nèi)容的改變(ftl引用config.ftl,模塊html打包結(jié)果輸出到config.ftl中)
  • ftl與html的改變绷雏,導(dǎo)致后端應(yīng)用的ftl模版引擎緩存與vanish的html緩存失效

跟飛哥提過之后發(fā)版本更新打包工具、修改了打包方式為第三種之后就解決了怖亭,目前NEJ的第三種打包方式已經(jīng)比較穩(wěn)定涎显,實現(xiàn)了文件名與文件內(nèi)容同步修改。

2兴猩、ndp的部署流程

在本地開發(fā)完畢之后期吓,需要部署到測試環(huán)境。目前基本上大多數(shù)產(chǎn)品都從omad遷移到了ndp倾芝。我們經(jīng)常會遇到在本地是好的讨勤,一部署就出現(xiàn)問題,而且遇到服務(wù)器前端基本就雞雞了晨另。但只要熟悉了ndp的整個部署流程悬襟,就算找后端GG幫忙排查問題也就變得so easy 了。
大家經(jīng)常遇到的問題如下:

  • 本地打包正常拯刁,ndp上構(gòu)建失敗脊岳。
    其實常見的就那么幾個原因:

    • 文件名引用大小寫問題,因為linux是嚴(yán)格區(qū)分大小寫的
    • 各種bower、npm安裝的依賴庫各種找不到
    • 各種bower安裝的組件版本沖突
  • 構(gòu)建部署成功割捅,但是頁面內(nèi)容還沒改變奶躯,各種懷疑人生,問題原因:

    • 代碼沒有push亿驾,包括工程嘹黔、組件
    • npm、bower 安裝使用了緩存莫瞬,沒有安裝更新后的文件
    • 服務(wù)器緩存或本地緩存

以上問題的解決排查方法基本如下:

  1. ssh登錄到ndp構(gòu)建機(jī)器上
  2. 業(yè)務(wù)代碼問題儡蔓,查看pub文件夾下打包出來的文件,查找具體的錯誤(nej打包錯誤會列出具體文件名疼邀、行號喂江、列號)
  3. 2的基礎(chǔ)上如果發(fā)現(xiàn)是bower、npm依賴包的問題旁振,那么可以npm cache clean | bower cache clean清掉緩存获询,再不行直接刪掉node_modules文件夾以及bower的lib文件夾,再重新安裝拐袜,還可以直接cd到具體文件查看文件內(nèi)容是否更新吉嚣。當(dāng)然清緩存的操作可以直接在寫腳本中,不需要登錄編譯機(jī)蹬铺,但是并不建議每次都清緩存尝哆,因為這會使得發(fā)布時間變長。

以上的問題排查過之后甜攀,發(fā)現(xiàn)文件已更新较解、部署成功頁面沒變或者報錯,基本可以去排查緩存赴邻、重啟vanish了

下面是我從wiki找到的一張ndp部署的流程圖印衔,部署流程清晰明了,中間缺了幾個前端的打包步驟與一些規(guī)定姥敛。


ndp上構(gòu)建機(jī)器打包過程.png

ndp上前端部署有一些規(guī)則需要遵守:
前端打包一般是打包到pub文件下

pub
├── h
│   └── web
├── s
│   └── web
└── v
    ├── edu
    └── web

然后拷貝到compressed文件夾下奸焙,compressed文件夾名稱是必須的,因為服務(wù)器上的腳本已經(jīng)固定名稱了彤敛。

前端打包流程.jpg

通過以上的流程圖与帆,應(yīng)該對ndp部署流程比較了解了吧。

ndp上的服務(wù)器大致分兩種:

  1. 靜態(tài)資源服務(wù)器墨榄,靜態(tài)資源js玄糟、css、html部署在這些機(jī)器上
  2. 應(yīng)用服務(wù)器袄秩,ftl部署在這些機(jī)器上

ndp的部署方式大概分兩種:

  1. 一鍵部署阵翎, 一鍵部署完成的順序具有不確定性逢并,緩存問題的發(fā)生也往往在這個階段。
  • ftl先完成郭卫,那么新版本ftl訪問新版本靜態(tài)資源404(采用第三種打包方式)砍聊,靜態(tài)資源服務(wù)器部署完成問題解決。新版本js請求模塊的html文件(html采用第二種打包方式)贰军,就有可能造成vanish緩存錯誤了
  1. 分組控制部署玻蝌, 默認(rèn)的部署方式,可以控制順序词疼,保證靜態(tài)資源先發(fā)布再發(fā)布ftl與后端應(yīng)用俯树。如果是先發(fā)布ftl并且使用nej第二種打包方式,就會出現(xiàn)新版本文件名緩存舊版本文件內(nèi)容的問題贰盗,如果使用了第三種打包方式许饿,就會出現(xiàn)靜態(tài)資源訪問不到的問題,等靜態(tài)資源發(fā)布之后就好了童太。

3米辐、后端服務(wù)器部署架構(gòu)

對于后端服務(wù)器的部署胸完,從挺兄那里了解到的一些信息书释,基本可以解釋清楚我們遇到的問題,首先是整個后端服務(wù)的架構(gòu)圖赊窥。


后端服務(wù)器部署架構(gòu)圖.png

后端的服務(wù)器部署架構(gòu)中有三塊緩存爆惧。

  • ftl模版緩存
    freemark模版引擎默認(rèn)設(shè)置緩存,后端應(yīng)用會有路徑指向ftl文件锨能,當(dāng)請求訪問應(yīng)用時讀取ftl返回并把ftl內(nèi)容緩存起來扯再,但是ftl文件內(nèi)容一改變,ftl模版引擎中的緩存就會被清掉址遇,所以在前端工程每次發(fā)布的時候緩存都已經(jīng)清掉了熄阻,不需要后端發(fā)布。

既然ftl的文件名稱不會改變倔约,使用第二種打包方式的話秃殉,ftl文件內(nèi)容不變,那沒有清緩存的必要浸剩,那么如果文件內(nèi)容改變钾军,緩存就自動清掉了,可是為啥會出現(xiàn)ftl緩存導(dǎo)致就頁面訪問到了新的靜態(tài)文件的問題呢绢要?當(dāng)然吏恭,ftl的緩存不僅僅是發(fā)生在服務(wù)器端,也可能發(fā)生在瀏覽器或者運(yùn)營商節(jié)點(diǎn)重罪,確認(rèn)過后端不會對ftl設(shè)置緩存樱哼,所以可能是瀏覽器本身問題或者運(yùn)營商的緩存哀九。

  • 靜態(tài)資源服務(wù)器的nginx緩存
    靜態(tài)資源服務(wù)器實現(xiàn)同名文件覆蓋式部署(不是直接覆蓋文件夾),不存在文件直接添加,所以文件夾下存在各個版本的靜態(tài)資源文件唇礁。但是采用nej第二種打包方式的話勾栗,文件名一樣,版本號不一樣并沒有用盏筐,在靜態(tài)資源服務(wù)器上文件名稱唯一围俘。服務(wù)器上的nginx服務(wù)監(jiān)測著這些文件的變化,文件一經(jīng)操作琢融,就會清掉nginx緩存中該文件的緩存界牡,所以每次部署,基本都是清掉nginx緩存漾抬,且nginx緩存不處理文件名后的參數(shù)宿亡,把a(bǔ).js?v=1與a.js?v=2當(dāng)作一個文件處理

  • 靜態(tài)資源的vanish緩存
    所有靜態(tài)文件的緩存,緩存設(shè)置時間為1天纳令,要清掉緩存只能重啟挽荠,這樣會影響到其他文件的緩存。vanish緩存處理文件版本參數(shù)平绩,a.js?v=1與a.js?v=2的會認(rèn)為是不同的文件圈匆,會同時緩存在內(nèi)存中,操作不慎捏雌,容易在vanish緩存中出現(xiàn)新版本名稱緩存了舊版本內(nèi)容的情況跃赚。

以上是整個部署流程中涉及到的東西的一些簡單闡述,如果有不對的地方性湿,歡迎指正纬傲,下面會列出以前遇到的問題和出現(xiàn)問題的原因。以下問題的出現(xiàn)主要是使用NEJ第二種打包方式:固定名稱?文件md5值格式肤频,問題的出現(xiàn)主要涉及到前后端誰先發(fā)布的問題叹括,也就是ftl與js、html誰先部署宵荒。請先認(rèn)真看過后端服務(wù)器部署架構(gòu)圖再看以下問題

前后端誰先發(fā)布的問題

  1. 第一次發(fā)布上線之后靜態(tài)資源服務(wù)器上存在core.js?v1, module2.js?v1與index.ftl,汁雷。module2引用的一些通用組件被打包在core.js中,如果版本不對應(yīng)很有可能報錯

  2. 第二次發(fā)布上線:
    前端先發(fā)
    那么此時靜態(tài)靜遠(yuǎn)服務(wù)器上存在core.js?v2, module2.js?v2骇扇。

    • 用戶訪問到了舊的ftl摔竿,且v1版本的資源在vanish緩存中未失效,vanish緩存返回v1版本文件少孝。


      舊ftl訪問vanish緩存中文件
    • 用戶訪問到了舊的ftl继低,且v1版本的資源在vanish緩存部分失效,vanish緩存返回部分v1版本文件稍走,然后去nginx中獲取同名v2版本文件返回袁翁,并在vanish緩存中設(shè)置以v1版本號為名而內(nèi)容為v2版本的緩存柴底,然后返回給客戶端,此時客戶端同時出現(xiàn)v1粱胜、v2文件柄驻,可能導(dǎo)致報錯,導(dǎo)致ftl未更新前所有用戶訪問都報錯焙压。
      舊ftl訪問部分舊版本文件鸿脓,部分新版本文件
    • 用戶訪問到了舊的ftl,且v1版本的資源在vanish緩存全部失效涯曲,請求全部請求新的文件并在vanish中形成緩存野哭,瀏覽器處理代碼引用正常,新版本js新加了接口發(fā)送到后端服務(wù)幻件,接口404


      舊ftl訪問訪問到新文件拨黔,新加接口404

在后端服務(wù)部署完成之前,用戶訪問到的都是老的ftl绰沥,都會出現(xiàn)這樣的情況篱蝇,等待后端服務(wù)部署好了用戶可以訪問到新的ftl之后問題就解決了。還有可能有些用戶由于瀏覽器本身緩存或者運(yùn)營商緩存徽曲,訪問到的還是老的ftl零截,這個只能由用戶自己處理了

后端服務(wù)先發(fā)
那么此時靜態(tài)靜遠(yuǎn)服務(wù)器上存在舊版本core.js?v1, module2.js?v1,且vanish緩存中未存在v2版本緩存疟位。

  • 用戶訪問到新版本ftl瞻润,ftl訪問新版本靜態(tài)資源喘垂,vanish緩存不存在甜刻,去靜態(tài)資源服務(wù)器請求并在vanish緩存中設(shè)置以v2版本號為名而內(nèi)容為v1版本的緩存,然后返回給客戶端正勒,且等待前端靜態(tài)資源發(fā)布完畢后緩存依然存在得院,后續(xù)請求在vanish緩存失效之前都不會去靜態(tài)資源服務(wù)器獲取最新的文件,所以拿到的都是錯誤文件章贞。且服務(wù)器端給客戶端設(shè)置的靜態(tài)資源緩存過期時間一般為7天祥绞,就算vanish緩存清掉了,如果用戶不會強(qiáng)制刷行瀏覽器的話鸭限,那問題可就大了
    新ftl訪問訪問到舊的資源文件并形成vanish緩存

以上問題的出現(xiàn)蜕径,都是在上線發(fā)布過程中發(fā)生的,現(xiàn)在的上線完成時間一般在幾分鐘到半個小時之間败京,這期間很大幾率有用戶訪問的兜喻,當(dāng)然如果可以嚴(yán)格控制部署的流程,可以大大降低問題發(fā)生的幾率赡麦。

比如采取后端先發(fā)且分組的方式來發(fā)布的朴皆,流程為:
流量切換到2組-->1組部署-->靜態(tài)資源部署-->流量切換到1組-->2組部署-->均衡流量帕识,聽說流量切換的速度挺快,所以這樣可以大大降低問題發(fā)生的幾率遂铡。當(dāng)然肮疗,這也是存在問題的,流程復(fù)雜了不說扒接,如果在流量高峰期伪货,很可能1組服務(wù)器根本滿足不了,會導(dǎo)致服務(wù)器全崩掉的钾怔,所以采取這種方式上線的都是在夜深人靜的時候超歌。

在現(xiàn)有開發(fā)流程中,為了保證上線后的穩(wěn)定性蒂教,部署環(huán)境會有多套巍举,且環(huán)境的切換方式是通過切換host的方式來實現(xiàn)的,新版本的發(fā)布前需要現(xiàn)在預(yù)發(fā)環(huán)境驗證通過之后才能發(fā)布上線凝垛,所以需要在不同環(huán)境中來回切換懊悯。基本上網(wǎng)站的域名都會分為主域名與靜態(tài)域名梦皮,即主域名訪問后端應(yīng)用ftl炭分,靜態(tài)域名訪問靜態(tài)服務(wù)器上的js、css剑肯、html等靜態(tài)文件捧毛。

我們經(jīng)常會遇到切換環(huán)境改host文件后并沒有及時切換的問題,必須要等一會或者強(qiáng)刷DNS緩存之后才起作用让网。既然有兩個域名的存在呀忧,我們從線上環(huán)境切換到預(yù)發(fā)環(huán)境時,也就可能出現(xiàn)域名切換不同步問題溃睹。情況如下:

  • 主域名已切換而账,靜態(tài)域名未切換
    請求訪問到預(yù)發(fā)新版的ftl因篇,而靜態(tài)資源為線上的舊版的靜態(tài)資源泞辐,出現(xiàn)問題同后端服務(wù)先發(fā)布的情況。意味著預(yù)發(fā)環(huán)境的請求造成了線上的緩存竞滓,在線上vanish緩存中新的文件名緩存著舊的文件內(nèi)容咐吼。這種情況發(fā)生以后,預(yù)發(fā)環(huán)境多刷幾遍緩存等host切換過來就沒問題了且在上線之前線上環(huán)境也是沒有問題的商佑。但在vanish緩存過期時間之內(nèi)上線了锯茄,就會出現(xiàn)新的ftl以新文件名稱訪問到舊的靜態(tài)資源內(nèi)容的問題。也就是大家經(jīng)常念叨的預(yù)發(fā)上好好的莉御,線上為啥就出問題了

    預(yù)發(fā)新ftl訪問線上資源造成線上vanish緩存中新版本文件名緩存舊文件內(nèi)容

  • 主域名未切換撇吞,靜態(tài)域名已切換
    那么訪問到的ftl為線上舊的ftl俗冻,而訪問到的靜態(tài)資源為預(yù)發(fā)環(huán)境的靜態(tài)服務(wù)器,雖然會造成在預(yù)發(fā)環(huán)境的vanish中舊版本文件名緩存新版本文件名的情況牍颈,但是等主域名切換過來之后問題就解決了迄薄,且不會對線上造成什么影響。


    線上舊ftl訪問預(yù)發(fā)靜態(tài)資源

以上問題的出現(xiàn)煮岁,其實主要是靜態(tài)資源服務(wù)器保存文件名與vanish緩存對文件版本號處理不一致所造成的讥蔽,要想解決服務(wù)器與vanish對文件處理方式一致問題,實現(xiàn)緩存及時更新,就需要實現(xiàn)文件名稱與文件內(nèi)容同步更新了。

NEJ的第三種打包方式唆香,前后兩次打包可以實現(xiàn)文件名與文件內(nèi)容同步更新,所以經(jīng)過兩次打包上線之后响禽,靜態(tài)服務(wù)器上大概會出現(xiàn)core_v1.js, core_v2.js, module_v1.js, module_v2.js, module2_v1.js (module_v1前后打包內(nèi)容不變,所以文件名不變)荚醒,按照以上兩個問題的方式來檢驗一下:

前端先部署

  • 舊版的ftl訪問core_v1.js, 請求到達(dá)vanish緩存芋类,core_v1.js存在返回,結(jié)果正常界阁。

  • 舊版的ftl訪問module_v1.js, 請求到達(dá)vanish緩存侯繁,module_v1.js緩存失效了不存在,那么請求到達(dá)靜態(tài)服務(wù)器泡躯,找到且返回給vanish緩存贮竟,并形成緩存,結(jié)果正常较剃。


    舊ftl訪問舊靜態(tài)資源咕别,不會造成錯誤緩存
  • 后端先部署
    新版本ftl訪問core_v2.js, 請求到達(dá)vanish緩存沒有,請求到達(dá)靜態(tài)服務(wù)器沒有重付,返回404顷级,客戶端報錯凫乖,等前端部署完成之后問題解決确垫,不會造成什么影響


    新ftl訪問新靜態(tài)資源,前端未發(fā)布返回404

使用NEJ第三種打包方式后帽芽,第一個問題基本上解決 删掀,除了上線期間如果后端先部署會短暫出現(xiàn)問題,但是可以通過分組方式避免的导街,且對后續(xù)不會造成影響披泪。

環(huán)境切換不完全問題

  • 主域名已切換,靜態(tài)域名未切換
    那么訪問到的ftl為預(yù)發(fā)新版的ftl搬瑰,而訪問到的靜態(tài)資源為線上的舊版的靜態(tài)資源款票,就是ftl訪問core_v2.js, 請求到達(dá)線上vanish緩存沒有控硼,然后請求線上靜態(tài)服務(wù)器都沒有,返回404艾少,切換完全后問題就解決卡乾,不會對線上緩存造成什么影響


    預(yù)發(fā)新ftl訪問線上資源返回404,不造成緩存
  • 主域名未切換缚够,靜態(tài)域名已切換
    那么訪問到的ftl為線上舊的ftl幔妨,而訪問到的靜態(tài)資源為預(yù)發(fā)環(huán)境的靜態(tài)服務(wù)器,就是ftl訪問core_v1.js谍椅,由于預(yù)發(fā)環(huán)境core_v1.js,core_v2.js同時存在误堡,所以可以訪問到core_v1.js文件,只是前端會煩惱明明都已經(jīng)發(fā)布成功了雏吭,為啥文件還是舊的
    預(yù)發(fā)新ftl訪問線上資源返回404锁施,不造成緩存

對于問題二, 不管怎么切換不完全杖们,都不會對線上造成什么影響沾谜,這是短暫對預(yù)發(fā)環(huán)境開發(fā)自己造成影響,所以出現(xiàn)這種問題時胀莹,記得檢查自己的請求ip是否正確了基跑。

NEJ的第三種打包方式與第二種相比,雖然同樣會遇到短暫的訪問錯誤問題描焰,但是真實解決的問題是避免造成錯誤緩存問題媳否,使用NEJ第三種打包方式,基本上可以解決目前常遇到的問題荆秦,NEJ的這種打包方式還是很好的篱竭,在處理服務(wù)器端緩存問題的同時,能做到文件名稱隨著文件內(nèi)容同步更新步绸,這就避免了如果只是小改變上下之后全部文件名改動造成全部緩存失效問題掺逼。

在解決這個問題的過程中,還討論瓤介、實施過其他的方法吕喘,比如我們的wap工程,采用了webpack打包,由于采用了ftl放在后端工程中前后端刑桑,前端只需要提供特定名稱的分離方式氯质,所以每次webpack打包出來的文件名稱都是固定的,文件的版本號由后端回填加上文件名稱后面當(dāng)版本號

// ftl文件只有一個default.ftl, 屬于多頁面單模版模式
// ftl中的pageName后端根據(jù)url判斷回填
// version由專門的后臺頁面配置祠斧,實時生效
<script src="${cdnUrl?default('')?html}/wap/s/${pageName?default('')?html}.js?v=${version?default('')?html}"></script>

發(fā)布順序為后端先發(fā)布闻察,然后前端發(fā)布,發(fā)布完成之后必須馬上修改版本號。那如果發(fā)布順序不固定會不會出現(xiàn)問題呢辕漂?答案是會的呢灶,可是緩存問題很容易得到解決,只需要再去升一下版本就好了钉嘹。

那么會不會出現(xiàn)環(huán)境切換不完全的問題的呢填抬,答案是會的,解決方法也很簡單隧期,去升級一下版本就好了飒责。

這種方式優(yōu)點(diǎn)很明顯,就是清掉緩存很簡單仆潮。同時也是缺點(diǎn)宏蛉,如果預(yù)發(fā)環(huán)境需要多次發(fā)布,每次都需要手動去修改版本號性置,而且每次上線之后版本號都要改變拾并,那么就會導(dǎo)致原本在vanish的緩存、在瀏覽器中的緩存全部失效鹏浅。

還有環(huán)境切換不完全造成線上緩存錯誤問題嗅义,后端GG提議不同環(huán)境使用不同的域名的方式解決該問題,當(dāng)然是可以解決的隐砸,而且切換環(huán)境就不需要切換host了之碗,如果使用切換host的方式來切換環(huán)境的話,使用NEJ第三種打包方式也是可以解決這個問題的季希,所以還是看情況褪那。

以上全部,可能還有其他奇怪的問題會出現(xiàn)(比如單獨(dú)打開靜態(tài)資源503式塌,而在頁面中可以訪問到的奇怪問題博敬,現(xiàn)場沒保留,無法排查)峰尝,本文說的不對的或者后續(xù)還有問題的偏窝,歡迎討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末武学,一起剝皮案震驚了整個濱河市祭往,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌劳淆,老刑警劉巖链沼,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沛鸵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門曲掰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疾捍,“玉大人,你說我怎么就攤上這事栏妖÷叶梗” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵吊趾,是天一觀的道長宛裕。 經(jīng)常有香客問我,道長论泛,這世上最難降的妖魔是什么揩尸? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮屁奏,結(jié)果婚禮上岩榆,老公的妹妹穿的比我還像新娘。我一直安慰自己坟瓢,他們只是感情好勇边,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著折联,像睡著了一般粒褒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诚镰,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天怀浆,我揣著相機(jī)與錄音,去河邊找鬼怕享。 笑死执赡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的函筋。 我是一名探鬼主播沙合,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼跌帐!你這毒婦竟也來了首懈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤谨敛,失蹤者是張志新(化名)和其女友劉穎究履,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脸狸,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡最仑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年藐俺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泥彤。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡欲芹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吟吝,到底是詐尸還是另有隱情菱父,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布剑逃,位于F島的核電站浙宜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛹磺。R本人自食惡果不足惜粟瞬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望称开。 院中可真熱鬧亩钟,春花似錦、人聲如沸鳖轰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕴侣。三九已至焰轻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昆雀,已是汗流浹背辱志。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狞膘,地道東北人揩懒。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像挽封,于是被迫代替她去往敵國和親已球。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理辅愿,服務(wù)發(fā)現(xiàn)智亮,斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,748評論 6 342
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,510評論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法点待,類相關(guān)的語法阔蛉,內(nèi)部類的語法,繼承相關(guān)的語法癞埠,異常的語法状原,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • 查理九世13萬字聋呢,查理是DODO冒險隊的老大,因為他很聰明遭笋,一只有著貴族血統(tǒng)的狗坝冕,濃重的黑眼圈是多么的可愛徒探,堯婷婷...
    生如夏花_380f閱讀 2,044評論 0 3