全站緩存時(shí)代

原則:動(dòng)靜分離,分級(jí)緩存棋嘲,主動(dòng)失效。

Web 開發(fā)中痪伦,接口會(huì)被分為以下幾類:

  1. 純靜態(tài)頁(yè)面阔籽。打死我都不會(huì)修改的頁(yè)面。很長(zhǎng)一段時(shí)間內(nèi)笆制,基本上不會(huì)修改。比如:關(guān)于我們证薇。
  2. 純動(dòng)態(tài)頁(yè)面匆篓。實(shí)時(shí)性,個(gè)性化要求比較高鸦概。頁(yè)面變化很大,或者每個(gè)用戶看到的都不一樣先慷,比如:朋友圈。
  3. 短時(shí)靜態(tài)頁(yè)面论熙。在一定時(shí)間內(nèi)基本不會(huì)變化,或者是容忍不需要實(shí)時(shí)更新无午。比如:文章祝谚、新聞。
  4. 動(dòng)靜結(jié)合頁(yè)面交惯。這個(gè)頁(yè)面既有動(dòng)態(tài),也有靜態(tài)內(nèi)容箕憾。也是實(shí)際應(yīng)用中最多的拳昌。

對(duì)于以上類型的頁(yè)面,可以做不同的緩存方案炬藤。各位大神們應(yīng)該根據(jù)自己業(yè)務(wù)的情況,靈活調(diào)整緩存方案上真。以下內(nèi)容可以作為參考羹膳。

模板渲染

高速發(fā)展的模板引擎,給前端渲染帶來了活力陵像。Mustache、jade妻怎、hbs 靈活的模板語(yǔ)法讓頁(yè)面開發(fā)變得更省力和高效泞歉。

HtmlDOM == VeiwEngine.render(template ,data);

瀏覽器只認(rèn)識(shí) DOM 結(jié)構(gòu)的字符串匿辩,也就是常說的 HTML5 格式榛丢。對(duì)于前端來渲染 DOM,還是后端渲染的問題,在此不用討論,為了情況前端的性能和體驗(yàn)挠阁,后端渲染會(huì)更合適。對(duì)于同一個(gè)頁(yè)面锨用,每次請(qǐng)求都會(huì)產(chǎn)生一次渲染嗎隘谣?渲染總是要計(jì)算的,這樣多浪費(fèi)服務(wù)器性能把捌纭!確實(shí)是這樣猾封,除非你用了緩存噪珊。

頁(yè)面緩存的方案

1. 純靜態(tài)頁(yè)面

直接放 CDN。純靜態(tài)頁(yè)面的訪問量一般不會(huì)很大痢站,程序直接響應(yīng)也是可以的。

2. 純動(dòng)態(tài)頁(yè)面

都說是動(dòng)態(tài)頁(yè)面了岳枷,那就不要做頁(yè)面緩存了呜叫。可以考慮做數(shù)據(jù)緩存家厌,或者是 redis、DB 緩存饭于。

3. 短時(shí)靜態(tài)頁(yè)面

1. 服務(wù)器端文件緩存

請(qǐng)求-->處理接口--> 模板渲染 ---> 存儲(chǔ)文件---> 響應(yīng)文件

緩存動(dòng)態(tài)頁(yè)面,你也可以把生成的文件存到 CDN果覆,然后讓 CDN 去響應(yīng)請(qǐng)求殖熟。如果你的請(qǐng)求需要過一些驗(yàn)證,那就把文件存儲(chǔ)到服務(wù)器菱属,由業(yè)務(wù)服務(wù)器去響應(yīng)請(qǐng)求。文件還有一個(gè)好處是:流薛耻。例如:FileReadStream.pipe(ResponseStream)赏陵。響應(yīng)的時(shí)候,不需要把文件的內(nèi)容加載到內(nèi)存蝙搔,而是直接用 stream 的方式響應(yīng)。但是弊端也不少倒淫,文件存儲(chǔ)败玉,會(huì)有并發(fā)讀寫死鎖問題。

還有一個(gè)問題运翼,分布式系統(tǒng)血淌。可能你有 A悠夯、B、C 三個(gè)服務(wù)器乳蓄。A 服務(wù)器生成了一個(gè)文件夕膀,還需要實(shí)時(shí)同步到 B 和 C美侦。當(dāng)然也可以讓 A魂奥、B、C 掛載同一個(gè)磁盤耻煤。問題又來了,這個(gè)文件要不要備份呢棺妓?

2. Redis Cache

請(qǐng)求--> 接口接口---> 模板渲染 --> 存儲(chǔ)數(shù)據(jù)--> 響應(yīng) DOM

把請(qǐng)求的 url 當(dāng)做 key买鸽,把模板渲染好的數(shù)據(jù)當(dāng)做值贯被,然后根據(jù)緩存規(guī)則,把數(shù)據(jù)存儲(chǔ)到 redis看幼。

這種小成本的緩存在我們的系統(tǒng)中有實(shí)踐幌陕,的確大幅提高了系統(tǒng)的響應(yīng)時(shí)間和 QPS,頁(yè)面的請(qǐng)求大部分是從 redis 讀數(shù)據(jù)搏熄,然后返回,單機(jī)測(cè)試過極限性能宵凌,14k QPS止后。簡(jiǎn)單描述一下。我們稱之為靜態(tài)化staticize

  1. 開始請(qǐng)求
  2. 請(qǐng)求校驗(yàn)瓜喇,filter 等等
  3. 查詢緩存 redis
  4. 如果有緩存歉糜,則直接響應(yīng)
  5. 沒有緩存,查詢數(shù)據(jù)匪补,重新渲染黍檩,存儲(chǔ)到 redis.
  6. 響應(yīng)
  7. 如果需更新緩存始锚,只需要?jiǎng)h掉對(duì)應(yīng)的redis 值

4. 動(dòng)靜結(jié)合的頁(yè)面

這種頁(yè)面在實(shí)際情況中更常見。原則:靜態(tài)頁(yè)面緩存棵里,動(dòng)態(tài)部分異步請(qǐng)求姐呐。

Paste_Image.png

靜態(tài)部分也是模板渲染過來的,瀏覽器會(huì)從 CDN 或者后臺(tái)緩存中獲取到靜態(tài)頁(yè)面头谜。頁(yè)面響應(yīng)的時(shí)間和瀏覽器的渲染會(huì)直接影響用戶體驗(yàn)鸠澈。動(dòng)態(tài)更新的部分一般會(huì)在一些細(xì)節(jié)部分,比如頁(yè)面的登錄狀態(tài)笑陈。對(duì)于所有用戶來說,我看到的這個(gè)頁(yè)面乖菱,只有用戶頭像部分會(huì)不一致蓬网。如果系統(tǒng)為每個(gè)用戶生成一個(gè)靜態(tài)頁(yè)面成本就太高了,而且完全沒必要墩新。

這個(gè)頁(yè)面就變成了:頁(yè)面 == 短時(shí)靜態(tài)頁(yè)面 + 局部動(dòng)態(tài)頁(yè)面窟坐。

『用戶狀態(tài)信息』這個(gè)特殊的動(dòng)態(tài)內(nèi)容,還需要用到本地的緩存機(jī)制哲鸳。用戶在切換頁(yè)面的時(shí)候,每個(gè)頁(yè)面都需要?jiǎng)討B(tài)加載用戶信息讯沈,所以我們的做法是在第一次請(qǐng)求到這個(gè)信息的時(shí)候婿奔,存儲(chǔ)到 localStorage问慎,然后設(shè)置過期時(shí)間挤茄。退出的時(shí)候,主動(dòng)清理 localStorage笼恰。

比如:個(gè)性化歇终,個(gè)人推薦這種因人而異的板塊都可以做成局部動(dòng)態(tài)頁(yè)面的形式。

5. 數(shù)據(jù)緩存

以上的方案同樣適用于異步請(qǐng)求评凝。

對(duì)于CDN 或者其他緩存來說,緩存不知道你存的內(nèi)容是 DOM 還是 JSON宜肉,還是其他格式篡诽。它只是幫你存儲(chǔ)數(shù)據(jù)榴捡。你同樣可以的把,數(shù)據(jù)接口达椰、局部 DOM 結(jié)構(gòu)(非完整 html 格式)存儲(chǔ)到 CDN 或者是 redis 中匆绣。比如:頁(yè)面的配置信息交播,或者從相關(guān)推薦系統(tǒng)請(qǐng)求的 dom 結(jié)構(gòu)蝇裤。

緩存更新

一般會(huì)有主動(dòng)失效和自動(dòng)失效緩存機(jī)制。

CDN 和 redis 等緩存都可以根據(jù)規(guī)則設(shè)置緩存時(shí)間栓辜。緩存過期后垛孔,會(huì)再次獲取新的數(shù)據(jù)。
主動(dòng)更新一般會(huì)用 API 調(diào)用方式實(shí)現(xiàn)狭莱。比如刪除 key,或者調(diào)用 CDN 接口進(jìn)行刪除操作

Paste_Image.png

緩存穿透

一般會(huì)在第一次請(qǐng)求的時(shí)候生成緩存,如果服務(wù)器端沒有緩存腋妙,然后在同一時(shí)刻出現(xiàn)高并發(fā)請(qǐng)求,請(qǐng)求會(huì)直接到達(dá)業(yè)務(wù)邏輯部分先壕,很可能導(dǎo)致系統(tǒng)直接掛掉谆甜。

解決辦法:

  1. 主動(dòng)創(chuàng)建緩存。緩存求由系統(tǒng)定時(shí)創(chuàng)建谆棺。
  2. 請(qǐng)求的時(shí)候設(shè)置標(biāo)志位罕袋。第一個(gè)請(qǐng)求到達(dá),標(biāo)識(shí)這個(gè) url 正在創(chuàng)建緩存浴讯,其他請(qǐng)求進(jìn)入等待隊(duì)列。

全站 CDN 加速

CDN 動(dòng)態(tài)加速如下圖所示:

Paste_Image.png

例如我的網(wǎng)站有以下接口和頁(yè)面:

  1. http://www.localhost.com/ // 短時(shí)緩存仰猖,動(dòng)靜結(jié)合
  2. http://www.localhost.com/api/user/1 // 純動(dòng)態(tài)
  3. http://www.localhost.com/post/hello-world // 永久靜態(tài)

所以奈籽,1衣屏、3頁(yè)面會(huì)放到 CDN,2 直接去源站請(qǐng)求狼忱。怎么做到呢?

  1. 在 CDN 配置自主源站佃却。意味著請(qǐng)求 CDN 地址的時(shí)候斧蜕,CDN 會(huì)去源站請(qǐng)求數(shù)據(jù),然后緩存到 CDN 節(jié)點(diǎn)。
  2. 設(shè)置緩存規(guī)則
    / 緩存 1 分鐘
    /post/* 緩存 1 年
    /api/ 不設(shè)置緩存
    
  3. cname www.localhost.com 到 CDN 提供的空間域名
Paste_Image.png

多平臺(tái) Mulit Origin

一個(gè) URL 可能會(huì)在不同的平臺(tái)有不同的返回和表現(xiàn)形式染坯。

產(chǎn)品的想法都是很完美丘逸,一個(gè)按鈕在不同的平臺(tái)會(huì)有不同的顯示狀態(tài)深纲。實(shí)際情況非常復(fù)雜,在我們的系統(tǒng)中湃鹊,出現(xiàn)過一個(gè)頁(yè)面出現(xiàn)在 七 個(gè)平臺(tái),每個(gè)平臺(tái)的顯示效果會(huì)不一致怀愧。不管是模板渲染余赢,或者是 js 處理按鈕狀態(tài)等等都是非常復(fù)雜的,或者 pc 和移動(dòng)端頁(yè)面表現(xiàn)出樣式和結(jié)構(gòu)差異妻柒。如果還要把這個(gè)頁(yè)面放到緩存,就更加復(fù)雜了绑警。

為每個(gè)平臺(tái)生成一份緩存啤贩?可以拜秧!

平臺(tái)的識(shí)別來自 UserAgent,不同的瀏覽器或者 app志衍,都有不同的UserAgent聊替。不同的來源我們稱之為 Origin。Origin + url 就可以生成唯一的 key惹悄,去識(shí)別唯一的緩存。緩存不限于 redis 和 文件緩存暂殖。

CDN 識(shí)別來源去讀取不同的文件,就需要 CDN 那邊做一些開發(fā)工作了呛每。Upyun、七牛這邊暫時(shí)不支持的洋腮。BAT這種大公司他們自己維護(hù)的 CDN 就能完美地做到手形。

另一種思路:

1個(gè)項(xiàng)目,兩個(gè)域名滤灯,2個(gè)動(dòng)態(tài) CDN曼玩。PC 和移動(dòng)端頁(yè)面分離、接口共享黍判。

例如:為同一個(gè)項(xiàng)目配置兩個(gè)域名:www.localhost.comm.www.localhost.com顷帖,同時(shí)為這兩個(gè)域名各設(shè)置一個(gè)動(dòng)態(tài) CDN。

由一項(xiàng)目提供兩個(gè)域名服務(wù)贬墩,比如:IndexController.main 處理請(qǐng)求 /homepage,移動(dòng)端和 PC 端的請(qǐng)求路徑分別為
* http://m.www.localhost.com/homepage
* http://www.localhost.com/homepage

main action 會(huì)根據(jù)請(qǐng)求來源url嗽测,分別渲染不同的頁(yè)面肿孵。不同的域名頁(yè)面,也就被不同的動(dòng)態(tài) CDN 緩存起來停做。

對(duì)于 /api/xxxx的接口,自然不需要做 PC 和移動(dòng)端或者其他平臺(tái)的區(qū)分官份,一個(gè) action 就可以解決了。這樣就避免了維護(hù)兩套系統(tǒng)的問題懈凹。

結(jié)語(yǔ)

以上介评,全站緩存基本完成爬舰。

不要憑空去拉高 QPS或者亂用緩存,根據(jù)你的業(yè)務(wù)和實(shí)際情況來對(duì)待情屹。最重要的事情就是要牢記:保持簡(jiǎn)潔,按需使用椅文。

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惜颇,隨后出現(xiàn)的幾起案子皆刺,更是在濱河造成了極大的恐慌,老刑警劉巖凌摄,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羡蛾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡锨亏,警方通過查閱死者的電腦和手機(jī)痴怨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來器予,“玉大人,你說我怎么就攤上這事乾翔“” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵末融,是天一觀的道長(zhǎng)钧惧。 經(jīng)常有香客問我暇韧,道長(zhǎng)勾习,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任懈玻,我火速辦了婚禮巧婶,結(jié)果婚禮上乾颁,老公的妹妹穿的比我還像新娘。我一直安慰自己艺栈,他們只是感情好英岭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著湿右,像睡著了一般诅妹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毅人,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天吭狡,我揣著相機(jī)與錄音,去河邊找鬼丈莺。 笑死划煮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缔俄。 我是一名探鬼主播弛秋,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼俐载!你這毒婦竟也來了蟹略?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤遏佣,失蹤者是張志新(化名)和其女友劉穎科乎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贼急,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茅茂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了太抓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片空闲。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖走敌,靈堂內(nèi)的尸體忽然破棺而出碴倾,到底是詐尸還是另有隱情,我是刑警寧澤掉丽,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布跌榔,位于F島的核電站,受9級(jí)特大地震影響捶障,放射性物質(zhì)發(fā)生泄漏僧须。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一项炼、第九天 我趴在偏房一處隱蔽的房頂上張望担平。 院中可真熱鬧示绊,春花似錦、人聲如沸暂论。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)取胎。三九已至展哭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闻蛀,已是汗流浹背摄杂。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留循榆,地道東北人析恢。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像秧饮,于是被迫代替她去往敵國(guó)和親映挂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理盗尸,服務(wù)發(fā)現(xiàn)柑船,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 【轉(zhuǎn)】緩存在分布式系統(tǒng)中的應(yīng)用 緩存在分布式系統(tǒng)中的應(yīng)用 摘要 緩存是分布式系統(tǒng)中的重要組件泼各,主要解決高并發(fā)鞍时,大數(shù)...
    武漢蘇乞兒閱讀 860評(píng)論 0 10
  • 緩存在分布式系統(tǒng)中的應(yīng)用 摘要 緩存是分布式系統(tǒng)中的重要組件,主要解決高并發(fā)扣蜻,大數(shù)據(jù)場(chǎng)景下逆巍,熱點(diǎn)數(shù)據(jù)訪問的性能問題...
    garyond閱讀 1,617評(píng)論 0 12
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,748評(píng)論 1 92
  • 今天我們一起來看看另外幾位的判詞莽使。 欲潔何曾潔锐极,云空未必空。 可憐金玉質(zhì)芳肌,終陷淖泥中灵再。 意思是:打算清新潔寂卻從未...
    無風(fēng)TINO閱讀 576評(píng)論 0 2