多亏我缓存技术过硬!疫情防控项目上线,我只用了5天!
先介紹下背景,我是武漢某O2O電商公司開發(fā)組長,疫情震中的我被老板要求7天之內(nèi)上線《疫情防控?zé)狳c(diǎn)圖》項(xiàng)目,幾個(gè)組員回老家斷網(wǎng),最終就2個(gè)人完成開發(fā)上線,滿足了10w+用戶的高頻訪問。時(shí)間和人力都緊張,不能按照常態(tài)模式開發(fā),很多技術(shù)選型也跟平時(shí)迥異。本文為大家專題分享一下緩存在本項(xiàng)目中的使用和踩的幾個(gè)典型的坑,希望對大家能有所幫助。
緩存Cache
緩存Cache是系統(tǒng)架構(gòu)、性能優(yōu)化的必備技能,也是新年跳槽季必考哦。核心思路就是把高頻耗資源數(shù)據(jù)找個(gè)地方存儲著,下次需要的時(shí)候直接使用,既能避免重復(fù)請求以降低壓力,也能更快捷獲取以提升性能??赡苡行』锇閮河X得疫情熱點(diǎn)圖要求實(shí)時(shí)更新,哪里用得上緩存?那你就太年輕了。本文一方面梳理下項(xiàng)目過程中各種緩存的原理、具體應(yīng)用場景,踩過的坑和解決辦法,另一方面也是希望拋磚引玉,歡迎大家多多,給予建議。
客戶端緩存
按慣例,從前往后說。客戶端緩存指的是讓瀏覽器將一些數(shù)據(jù)緩存重用,避免重復(fù)請求?;驹硎抢肏ttp協(xié)議緩存協(xié)商,在ResponseHeader里面指定下緩存策略即可,適合緩存一些靜態(tài)資源。
本項(xiàng)目中用的非常多,各種css、js和小圖標(biāo)文件,都直接設(shè)置了30天緩存有效期,資源更新時(shí),采用的是版本號緩存更新模式,直接在每個(gè)資源請求后面都帶上了版本號,簡單粗暴完成緩存更新。? ? ? ? ? ?
CND緩存&反向代理緩存
?????? CDN緩存和反向代理緩存的思路是差不多的,一個(gè)Http請求要經(jīng)過DNS,要經(jīng)過反向代理,那么在這兩個(gè)環(huán)節(jié)加一層緩存也是必須的。不過由于項(xiàng)目開發(fā)周期短,7天就要求上線,CDN沒折騰,反向代理緩存倒是立了大功。
項(xiàng)目的后端是3個(gè)Core WebApi服務(wù)實(shí)例構(gòu)建的集群,用Nginx做的負(fù)載均衡,然后加了個(gè)緩存解決了一個(gè)高頻場景,小區(qū)周邊疫情熱點(diǎn)圖。用Url+小區(qū)Id作為key,直接緩存了整個(gè)動態(tài)頁,有效期1小時(shí)。很多用戶進(jìn)來就是看下自己小區(qū)熱點(diǎn)圖然后關(guān)閉了,差不多攔截了40%的請求量,反向代理緩存效果不要太牛!
本地緩存&分布式緩存
兩個(gè)都是服務(wù)端緩存,Asp.Net Core內(nèi)置了MemoryCache作為本地緩存,也非常友好的支持了Redis分布式緩存,二者都是利用內(nèi)存緩存數(shù)據(jù)重用以加快速度。由于后端是做的集群,為方便緩存共享,只用了Redis分布式緩存。
能緩存的數(shù)據(jù)就很多了,項(xiàng)目里幾乎全部的數(shù)據(jù)都走了一遍緩存,即使是大家認(rèn)為的實(shí)時(shí)數(shù)據(jù),項(xiàng)目里面也是采用的雙寫方案,同步寫數(shù)據(jù)庫和Redis,查詢直接走的Redis。此外,為減小數(shù)據(jù)寫入壓力,像用戶登錄、瀏覽記錄、頁面訪問次數(shù)等即時(shí)信息也都是放在Redis里面的,滿100次或者1h才同步一次數(shù)據(jù)庫。
緩存的坑
?????? 正常狀況下的緩存使用還是挺簡單的,最怕是遇到異常情況。這次項(xiàng)目不大,但是因?yàn)闀r(shí)間倉促,很多細(xì)節(jié)沒處理好,幾個(gè)緩存常見的坑都給踩了一遍。
?????? 系統(tǒng)是在催促中上線的,沒有經(jīng)過任何緩存預(yù)熱,直接公眾號push了一波通知,流量短時(shí)間沖上去了,這時(shí)候Redis里面還是空的,請求直接都到數(shù)據(jù)庫了,上線10分鐘后就掛了。解決辦法是快速寫了個(gè)控制臺,把數(shù)據(jù)訪問了一遍,初始化到Redis里面完成緩存預(yù)熱就可以了。
???????
然而,填完這個(gè)坑,又引出了新的坑。緩存預(yù)熱時(shí)沒注意緩存有效期的設(shè)置,緩存預(yù)熱時(shí)將數(shù)據(jù)的過期時(shí)間都設(shè)置成了4小時(shí),結(jié)果在4小時(shí)之后大量緩存同時(shí)過期,請求都到數(shù)據(jù)庫了,幸虧當(dāng)時(shí)是晚上10點(diǎn),數(shù)據(jù)庫好歹沒倒。火速把項(xiàng)目升級了一下,將過期時(shí)間做了個(gè)隨機(jī)變化,避免因?yàn)橥瑫r(shí)過期而造成的緩存雪崩。
?????? 最后是項(xiàng)目運(yùn)行一周后,發(fā)現(xiàn)數(shù)據(jù)庫的壓力突然又上來了。通過日志排查發(fā)現(xiàn)是某個(gè)IP一直用一個(gè)不存在的數(shù)據(jù)Id高頻訪問(猜測是友商在測試),因?yàn)閿?shù)據(jù)庫沒有這個(gè)數(shù)據(jù),緩存總是無法命中,導(dǎo)致請求都穿透緩存到了數(shù)據(jù)庫。解決辦法也簡單,緩存邏輯加了個(gè)key-null,沒有數(shù)據(jù)也能緩存。
?????? 上面整理了項(xiàng)目中各種緩存的基本原理和使用場景,也總結(jié)了自己踩的幾個(gè)坑,希望能給大家一些幫助,也歡迎大家交流拍磚。具體的代碼實(shí)現(xiàn)沒法為大家一一展示(項(xiàng)目還在運(yùn)營),不過我這里很用心的為大家推薦一個(gè)課程,是我最崇拜的Eleven老師講的,文中關(guān)于緩存的方方面面都會覆蓋到(本文也是應(yīng)Eleven老師邀請寫的),而且還是免費(fèi)的哦!
福
利
福
利
福
利
? 最后,體貼的Eleven老師還說了,要給大家準(zhǔn)備一組預(yù)習(xí)資料,方便大家的學(xué)習(xí),大家趕緊掃碼加美女小助教領(lǐng)取免費(fèi)預(yù)習(xí)資料咯。架構(gòu)師之路,道阻且長,愿大家一起共同成長!
總結(jié)
以上是生活随笔為你收集整理的多亏我缓存技术过硬!疫情防控项目上线,我只用了5天!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 借助Redis完成延时任务
- 下一篇: ABP框架使用拦截器动态配置租户过滤器