为什么要使用页面缓存技术
為什么要使用頁面緩存技術(shù)
一、總結(jié)
一句話總結(jié):
系統(tǒng)的瓶頸往往是來自于數(shù)據(jù)庫,我們可以使用緩存來減少對數(shù)據(jù)庫的訪問!
系統(tǒng)都是逐漸演進的,一個系統(tǒng)在運行中必須是根據(jù)場景逐漸地提高優(yōu)化性能。高并發(fā)就是對資源的節(jié)約的考驗,這種考驗除了更換優(yōu)秀和先進的技術(shù),優(yōu)化架構(gòu),還在于從小處出發(fā),對盡可能節(jié)約的資源進行節(jié)約。而在一個系統(tǒng)的數(shù)據(jù)訪問中,系統(tǒng)的瓶頸往往是來自于數(shù)據(jù)庫,因此我們要盡可能減少對數(shù)據(jù)庫的訪問!在不影響用戶體驗的情況下,對于一些靜態(tài)或者變化不大的頁面,我們使用緩存來減少對數(shù)據(jù)庫的訪問!
?
1、緩存提高系統(tǒng)訪問速度的原理是什么?
緩存可以降低 邏輯復雜度,訪問數(shù)據(jù)庫次數(shù),從未大幅減少服務(wù)器響應(yīng)時間
我們都知道在一個請求中,邏輯越復雜,調(diào)用,依賴,訪問數(shù)據(jù)庫的越多,耗時也就越長,響應(yīng)時間也就越長,性能也就越差!因此降低邏輯復雜度,減低耦合,提高內(nèi)聚,減少數(shù)據(jù)庫訪問,將頻繁用到的變化不大的數(shù)據(jù)給緩存起來也就成為了提高性能的主要核心。
?
2、使用緩存的核心通用邏輯是什么?
當客戶的請求到達后端時,先去redis中查詢緩存,如果緩存中找不到,則進行數(shù)據(jù)庫邏輯操作,然后渲染,存入緩存并返回給前端!如果在緩存中找到了則直接返回給前端。
存儲在Redis緩存中的頁面需要設(shè)置超時時間,緩存的時間長度根據(jù)頁面數(shù)據(jù)變化頻繁程度適當調(diào)整!目前大多數(shù)頁面緩存都是在60~120秒,少數(shù)幾乎不變化的可以調(diào)整到5分鐘!
?
3、頁面緩存的時間如何設(shè)置?
緩存的時間長度根據(jù)頁面數(shù)據(jù)變化頻繁程度適當調(diào)整!目前大多數(shù)頁面緩存都是在60~120秒,少數(shù)幾乎不變化的可以調(diào)整到5分鐘!
?
4、熱點數(shù)據(jù)是什么?
所謂熱點數(shù)據(jù),就是指在某段時間內(nèi)被頻繁使用的對象數(shù)據(jù)。比如用戶登錄信息、點贊信息、網(wǎng)站人數(shù)。
所謂熱點數(shù)據(jù),就是指在某段時間內(nèi)被頻繁使用的對象數(shù)據(jù)。比如用戶登錄信息,用戶在登錄后,每次訪問都會攜帶其cookie信息進入后端,當信息到達后端后,其cookie信息就是我們存在redis中的key值。在這一步我們會做四個操作,并且在某些時候可使用攔截器進行處理:
?
5、熱點數(shù)據(jù)緩存思路是什么?
頻繁更新的數(shù)據(jù):比如點贊次數(shù),在線人數(shù),達到一定的量后再一次性更新。
量大的數(shù)據(jù):數(shù)據(jù)庫更新的時候同時更新緩存,每次從緩存中取。
全局信息:比如用戶名信息,設(shè)置全局緩存。
?
<1>當用戶操作進來的時候,我們獲取到Cookie值并在Redis中查找,找到用戶信息則刷新用戶的登錄時間并允許用戶通過,找不到用戶信息則拒絕用戶繼續(xù)往下!,在后面的數(shù)據(jù)操作中,如果存在需要使用用戶信息的操作,則去Redis中查找,如果存在則允許操作!
<2>對于熱點數(shù)據(jù)源,被高頻訪問的不缺分權(quán)限信息的熱點數(shù)據(jù),則設(shè)置全局緩存,定時更新則緩存數(shù)據(jù),當有操作到此類的熱點數(shù)據(jù)緩存則主動更新緩存中的信息,將用戶攔截在數(shù)據(jù)之外!
<3>當涉及到用戶登錄的熱點數(shù)據(jù)被更新后,需要根據(jù)用戶的token作為key值重新寫入或者強制用戶重新登錄!
<4>對于需要頻繁更新的數(shù)據(jù)或?qū)懭霐?shù)據(jù)的數(shù)據(jù),比如點贊次數(shù),在線人數(shù),可以設(shè)置一個層級,在沒有達到層級前寫在緩存中,每次只更新緩存則可以,當?shù)揭欢ù螖?shù)則寫入數(shù)據(jù)庫!
?
6、緩存雪崩是什么?
緩存雪崩是指因為數(shù)據(jù)未加載到緩存中,或者緩存同一時間大面積的失效,在某一時刻大量的緩存沒有命中,從而導致所有請求都去查數(shù)據(jù)庫,導致數(shù)據(jù)庫CPU和內(nèi)存負載過高,甚至宕機!
?
7、造成緩存雪崩的可能原因及預(yù)防?
緩存穿透:對所有可能查詢的參數(shù)以hash形式存儲,在控制層先進行校驗,不符合則丟棄:查詢一個數(shù)據(jù)庫必然不存在的數(shù)據(jù),那么緩存里面也沒有。如果有人惡意破壞,發(fā)送高頻請求,那么很可能直接對DB造成影響。
緩存失效:盡量讓失效時間點均勻分布:如果緩存集中在一段時間內(nèi)失效,DB的壓力凸顯,DB負載急劇上升
緩存預(yù)熱:開發(fā)人員主動將數(shù)據(jù)加載到緩存中:系統(tǒng)部署時,防止用戶一瞬間訪問數(shù)據(jù)庫,負載過大
1. 緩存穿透:查詢一個數(shù)據(jù)庫必然不存在的數(shù)據(jù),那么緩存里面也沒有。比如文章表中查詢一個不存在的id,每次都會訪問DB,如果有人惡意破壞,發(fā)送高頻請求,那么很可能直接對DB造成影響。
解決辦法:對所有可能查詢的參數(shù)以hash形式存儲,在控制層先進行校驗,不符合則丟棄?;蛘邔τ诓樵?yōu)榭盏淖侄?#xff0c;設(shè)置一個默認值在緩存中,如果查詢到則返回默認值! 或者使用具備特點的key值,如果不符合則經(jīng)由于系統(tǒng)過濾掉,不進入緩存也不進入數(shù)據(jù)庫,此做法可以降低一定的壓力,但是解決不了根本的問題。
2.緩存失效:如果緩存集中在一段時間內(nèi)失效,DB的壓力凸顯,DB負載急劇上升。這個沒有完美解決辦法,但可以分析用戶行為,盡量讓失效時間點均勻分布。
3.緩存預(yù)熱:系統(tǒng)部署時,防止用戶一瞬間訪問數(shù)據(jù)庫,負載過大,由開發(fā)人員主動將數(shù)據(jù)加載到緩存中!
?
?
8、靜態(tài)資源優(yōu)化方式?
1.JS/CSS壓縮,靜態(tài)資源盡量使用壓縮版的庫和包,以減少瀏覽器加載和請求的流量
2.多個js/css組合到一個請求,減少連接數(shù)(正常30個,從服務(wù)端獲取,多次訪問,通過http獲取),把多個文件通過一個js/css一次性請求下來 配置 tengine模塊實現(xiàn)!
3.將多個Js/css的請求合并為一個
4.CDN:用于解決網(wǎng)絡(luò)擁擠:內(nèi)容分發(fā)網(wǎng)絡(luò),將數(shù)據(jù)緩存到網(wǎng)絡(luò)節(jié)點上,用戶請求來根據(jù)位置定向訪問到距離最近的節(jié)點,可用于解決網(wǎng)絡(luò)擁擠,跟代碼層面關(guān)系不是很大,在請求沒到網(wǎng)站之前,CDN會根據(jù)客戶的位置將請求分發(fā)到就近地網(wǎng)路節(jié)點上,如果節(jié)點有則直接返回!
?
?
?
二、頁面優(yōu)化緩存技術(shù)+資源靜態(tài)化+前后端分離?
參考:頁面優(yōu)化緩存技術(shù)+資源靜態(tài)化+前后端分離?
https://blog.csdn.net/qq_36505948/article/details/82620908
《目錄》
---------->緩存的需要,緩存的原理
---------->頁面緩存的思路
---------->熱點數(shù)據(jù)緩存的思路,4個點
---------->頁面局部緩存(與靜態(tài)緩存的信息是相似的)
---------->緩存可能引起的問題以及解決思路
---------->由于后端跳轉(zhuǎn)頁面轉(zhuǎn)向ajax技術(shù)請求參數(shù)的頁面靜態(tài)化技術(shù)與思路,這一步也是前后端分離的實現(xiàn)
---------->SpringBoot的設(shè)置使得靜態(tài)頁面緩存在瀏覽器,與瀏覽器的基本查看
一、為什么要使用頁面緩存技術(shù)?
系統(tǒng)都是逐漸演進的,一個系統(tǒng)在運行中必須是根據(jù)場景逐漸地提高優(yōu)化性能。高并發(fā)就是對資源的節(jié)約的考驗,這種考驗除了更換優(yōu)秀和先進的技術(shù),優(yōu)化架構(gòu),還在于從小處出發(fā),對盡可能節(jié)約的資源進行節(jié)約。而在一個系統(tǒng)的數(shù)據(jù)訪問中,系統(tǒng)的瓶頸往往是來自于數(shù)據(jù)庫,因此我們要盡可能減少對數(shù)據(jù)庫的訪問!在不影響用戶體驗的情況下,對于一些靜態(tài)或者變化不大的頁面,我們使用緩存來減少對數(shù)據(jù)庫的訪問!
二、緩存技術(shù)的原理?
我們都知道在一個請求中,邏輯越復雜,調(diào)用,依賴,訪問數(shù)據(jù)庫的越多,耗時也就越長,響應(yīng)時間也就越長,性能也就越差!因此降低邏輯復雜度,減低耦合,提高內(nèi)聚,減少數(shù)據(jù)庫訪問,將頻繁用到的變化不大的數(shù)據(jù)給緩存起來也就成為了提高性能的主要核心。
1.頁面緩存思路:
首先我們需要明白,一個頁面是從后端提高數(shù)據(jù)后,交給springMvc或者SpringBoot進行渲染,主要的頁面消耗是在渲染這部分。因此我們需要在這之前進行攔截。(針對于依靠后端進行頁面跳轉(zhuǎn)和渲染的緩存初始階段)
核心通用邏輯:當客戶的請求到達后端時,先去redis中查詢緩存,如果緩存中找不到,則進行數(shù)據(jù)庫邏輯操作,然后渲染,存入緩存并返回給前端!如果在緩存中找到了則直接返回給前端。存儲在Redis緩存中的頁面需要設(shè)置超時時間,緩存的時間長度根據(jù)頁面數(shù)據(jù)變化頻繁程度適當調(diào)整!目前大多數(shù)頁面緩存都是在60~120秒,少數(shù)幾乎不變化的可以調(diào)整到5分鐘!
2.熱點數(shù)據(jù)緩存思路:
所謂熱點數(shù)據(jù),就是指在某段時間內(nèi)被頻繁使用的對象數(shù)據(jù)。比如用戶登錄信息,用戶在登錄后,每次訪問都會攜帶其cookie信息進入后端,當信息到達后端后,其cookie信息就是我們存在redis中的key值。在這一步我們會做四個操作,并且在某些時候可使用攔截器進行處理:
<1>當用戶操作進來的時候,我們獲取到Cookie值并在Redis中查找,找到用戶信息則刷新用戶的登錄時間并允許用戶通過,找不到用戶信息則拒絕用戶繼續(xù)往下!,在后面的數(shù)據(jù)操作中,如果存在需要使用用戶信息的操作,則去Redis中查找,如果存在則允許操作!
<2>對于熱點數(shù)據(jù)源,被高頻訪問的不缺分權(quán)限信息的熱點數(shù)據(jù),則設(shè)置全局緩存,定時更新則緩存數(shù)據(jù),當有操作到此類的熱點數(shù)據(jù)緩存則主動更新緩存中的信息,將用戶攔截在數(shù)據(jù)之外!
<3>當涉及到用戶登錄的熱點數(shù)據(jù)被更新后,需要根據(jù)用戶的token作為key值重新寫入或者強制用戶重新登錄!
<4>對于需要頻繁更新的數(shù)據(jù)或?qū)懭霐?shù)據(jù)的數(shù)據(jù),比如點贊次數(shù),在線人數(shù),可以設(shè)置一個層級,在沒有達到層級前寫在緩存中,每次只更新緩存則可以,當?shù)揭欢ù螖?shù)則寫入數(shù)據(jù)庫!
2.頁面局部緩存:
熱點數(shù)據(jù)緩存,頁面靜態(tài)化進行ajax請求信息更新,此類信息一般都是比較頻繁發(fā)生變化的,涉及的可能是需要保存在數(shù)據(jù)庫的操作,類似表格信息,即時刷新的數(shù)據(jù)等!如果是屬于查看類的并且前端大量請求,可以經(jīng)由于后端監(jiān)控,定時寫入緩存!
核心通用邏輯:一般情況下封裝以類名--對象名為組合的字符串作為Redis的Key值,然后存入數(shù)據(jù)庫,每次訪問到目標的方法都先去緩存讀取,然后再處理!
三、緩存雪崩-數(shù)據(jù)穿透問題:
緩存雪崩:緩存雪崩是指因為數(shù)據(jù)未加載到緩存中,或者緩存同一時間大面積的失效,在某一時刻大量的緩存沒有命中,從而導致所有請求都去查數(shù)據(jù)庫,導致數(shù)據(jù)庫CPU和內(nèi)存負載過高,甚至宕機!
1. 緩存穿透:查詢一個數(shù)據(jù)庫必然不存在的數(shù)據(jù),那么緩存里面也沒有。比如文章表中查詢一個不存在的id,每次都會訪問DB,如果有人惡意破壞,發(fā)送高頻請求,那么很可能直接對DB造成影響。
解決辦法:對所有可能查詢的參數(shù)以hash形式存儲,在控制層先進行校驗,不符合則丟棄?;蛘邔τ诓樵?yōu)榭盏淖侄?#xff0c;設(shè)置一個默認值在緩存中,如果查詢到則返回默認值! 或者使用具備特點的key值,如果不符合則經(jīng)由于系統(tǒng)過濾掉,不進入緩存也不進入數(shù)據(jù)庫,此做法可以降低一定的壓力,但是解決不了根本的問題。
2.緩存失效:如果緩存集中在一段時間內(nèi)失效,DB的壓力凸顯,DB負載急劇上升。這個沒有完美解決辦法,但可以分析用戶行為,盡量讓失效時間點均勻分布。
3.緩存預(yù)熱:系統(tǒng)部署時,防止用戶一瞬間訪問數(shù)據(jù)庫,負載過大,由開發(fā)人員主動將數(shù)據(jù)加載到緩存中!
單機---系統(tǒng):手動刷新頁面既可以了,或者定時緩存緩存
分布式系統(tǒng): 分布式系統(tǒng)問題在于數(shù)據(jù)量非常大,緩存可能會導致數(shù)據(jù)庫宕機!通過程序進行單個緩存加載!
四、Redis頁面緩存實現(xiàn)
1.請求到來后,先調(diào)用根據(jù)key值去redis訪問,找到則返回
2.SpringBoot的redis中找不到調(diào)用webConext()對象進行加載
1. 將Thyemleaf的thymeleafViewResolver給注入到Controller中 2. 進行頁面渲染:WebContext ctx=new WebContext(request,response,request.getServletContext(),request.getLocale(),model.asMap());html=thymeleafViewResolver.getTemplateEngine().process("頁面名稱無后綴",ctx); 3. 返回頁面信息 ================================================================================================ 方法的返回以String對象,并且頁面不可以使用ResController作為注解(以json返回),頁面的reqestMapper里 設(shè)置:@RequestMapping(value = "/xxxx",produces ="text/html")//可能沒有數(shù)據(jù)@ResponseBody3.SpringMvc的redis中使用攔截器或者過濾器用ModelAndView渲染,攔截器的用法過于簡單,自行百度,不做解釋
五、頁面靜態(tài)化?
除了將頁面資源與數(shù)據(jù)進行緩存以減少數(shù)據(jù)庫訪問外,還可以利用瀏覽器特點,將頁面給完全緩存在瀏覽器中,等到瀏覽器過時,再訪問項目,項目的請求經(jīng)過項目內(nèi)部緩存,緩存如果過時,再訪問數(shù)據(jù)庫!
將頁面靜態(tài)化的特點必須解決頁面如何獲取與處理數(shù)據(jù),如何跳轉(zhuǎn)頁面的問題!在此我們可以參考 ajax技術(shù) ,將請求與頁面完全獨立,保證頁面是靜態(tài)頁面,而請求通過Ajax技術(shù)局部刷新與全局刷新的特點來實現(xiàn)!變化如下:
1----原流程?
2----靜態(tài)化頁面流程?
注意:此流程為頁面靜態(tài)化的流程,前端的頁面跳轉(zhuǎn)將由頁面之間直接完成,不在通過后端!頁面之間的數(shù)據(jù)加載,則是通過Ajax請求的形式,請求后端返回JSON數(shù)據(jù)流。在請求中有緩存則顯訪問緩存,沒有緩存或者緩存超時則直接訪問下一層,知道完整返回數(shù)據(jù)!
3------瀏覽器設(shè)置與分析?
一般情況下,一個正常的請求都具備了請求報文和響應(yīng)報文,請求和響應(yīng)均分成三個部分,請求頭則維護了請求協(xié)議類型,而請求和響應(yīng)報文則維護了對于報文體的參數(shù),生命,來源等信息!第三部分則是本次請求的內(nèi)容,也就是我們說的報文體!對于瀏覽器來說,他更像是一個負責頁面渲染和參數(shù)設(shè)定的容器,讀取報文頭的信息對報問題進行相關(guān)的操作,并通過一定的通過規(guī)則展示給使用者!
瀏覽器的主要功能是將用戶選擇的web資源呈現(xiàn)出來,它需要從服務(wù)器請求資源,并將其顯示在瀏覽器窗口中,資源的格式通常是HTML,也包括PDF、image及其他格式。 HTML和CSS規(guī)范中規(guī)定了瀏覽器解釋html文檔的方式,由W3C組織對這些規(guī)范進行維護,W3C是負責制定web標準的組織。
關(guān)于瀏覽器原理可以參考:https://kb.cnblogs.com/page/129756/
頁面靜態(tài)化的一個特點也是可以將靜態(tài)頁面給緩存在用戶瀏覽器一端。同一個頁面,在頁面的生命周期沒到之前,用戶的請求都是在本地進行(304);
用于識別是否緩存并且區(qū)分緩存時間的主要是以下三個模塊:
Pragma:支持http1.0版本的緩存
Expire:http2.0可以用,也向下兼容http1.0版本,16進制的字符串,以格里尼治時間也準,以服務(wù)端時間來定義緩存你是否超時,但由于客戶端與服務(wù)端緩存時間經(jīng)常不一致,所以容易造成緩存失效!
Cache-control:Http版本1.0-2.0都可以用,以秒為單位,并且可以指定緩存為多少秒,對緩存時間進行倒計時,同時不會根據(jù)客戶端時間來衡量,也不會根據(jù)服務(wù)端時間衡量,完全依賴信息本身!
cache-control=max-age=3600:服務(wù)端告訴瀏覽器指定3600秒
觀察:在網(wǎng)絡(luò)XHR上面的連接輸出字段可以看到連接已經(jīng)緩存,在緩存有效期內(nèi),每一次請求都是返回304,但只是瀏覽器自己處理,實際請求并沒有到達后端系統(tǒng)!
在springBoot后端的application.yml做如下設(shè)置:
resources:add-mappings: true #配置chain:cache: trueenabled: truegzipped: true#是否執(zhí)行壓縮html-application-cache: true #是否啟動html引用的緩存static-locations: classpath:/static/ #靜態(tài)資源頁面的位置cache-period: 3600 #頁面瀏覽器的配置緩存多少秒 ============================================================================================ 將該信息放置于spring的節(jié)點下4-----靜態(tài)資源優(yōu)化?
除了對靜態(tài)頁面優(yōu)化,我們還可以通過一些方式減少流量,提供訪問的速度!當用戶的請求越小,性能也就相對越好!
1.JS/CSS壓縮,靜態(tài)資源盡量使用壓縮版的庫和包,以減少瀏覽器加載和請求的流量
2. 多個js/css組合到一個請求,減少連接數(shù)(正常30個,從服務(wù)端獲取,多次訪問,通過http獲取),把多個文件通過一個js/css一次性請求下來 配置 tengine模塊實現(xiàn)!
3.將多個Js/css的請求合并為一個
4.CDN:內(nèi)容分發(fā)網(wǎng)絡(luò),將數(shù)據(jù)緩存到網(wǎng)絡(luò)節(jié)點上,用戶請求來根據(jù)位置定向訪問到距離最近的節(jié)點,可用于解決網(wǎng)絡(luò)擁擠,跟代碼層面關(guān)系不是很大,在請求沒到網(wǎng)站之前,CDN會根據(jù)客戶的位置將請求分發(fā)到就近地網(wǎng)路節(jié)點上,如果節(jié)點有則直接返回!
注意:tengine與nginx的功能基本是一樣的,繼承了nginx所有特性,并且擁有可以對靜態(tài)資源壓縮合并請求等功能,詳情可參考tengine.taobaoorg ,可以參照Nginx的方式來配置Tengine!
六--------對于緩存?
對于一個項目來說,其瓶頸往往是在于數(shù)據(jù)庫的瓶頸。除了業(yè)務(wù)代碼的穩(wěn)定性,我們所做的操作目的都是在減少數(shù)據(jù)庫的壓力。通過Redis頁面緩存,通過瀏覽器緩存,通過頁面靜態(tài)化,通過Redis頁面靜態(tài)緩存,通過Redis熱點數(shù)據(jù)緩存,Nginx緩存,Tengine緩存,CDN緩存等,層層攔截,以減少對數(shù)據(jù)庫的訪問!
但是對于數(shù)據(jù)來說,一切的緩存都是建立在不影響客戶體驗的基礎(chǔ)上,緩存因為其特點,仍熱存在著數(shù)據(jù)不同步的問題!
針對這個問題,能處理的只有?
定時刷新緩存,存儲變化非常小的頁面信息!
主動監(jiān)控更新緩存!
轉(zhuǎn)載于:https://www.cnblogs.com/Renyi-Fan/p/10907658.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的为什么要使用页面缓存技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2.7 HBase架构深入剖析
- 下一篇: 2019-05-23 IRIS嗅探器;用