使用緩存(Cache)的幾種方式,回顧一下~~~


前言

如今緩存成為了優化網站性能的首要利器,緩存使用的好,不僅能讓網站性能提升,讓用戶體驗變好,而且還能節約成本(增加一台緩存服務器可能就節約好幾台機器);那平時小伙伴們都使用哪些緩存方式呢?這里就來和小伙伴們一起來回顧一下。

正文

緩存的作用其實很明確,如下兩方面:

  • 提升數據的獲取速度

    通常用在獲取數據速度要求比較高的場景,比如一些和設備通信的軟件,對時間的要求比較高,如果每次都從數據庫讀數據會導致消耗多余的時間。

  • 減輕后台應用或數據庫服務器的負載

    對於高並發場景的系統,如果每次請求都打到數據庫,數據庫服務器負載會變大,到達一定瓶頸之后可能讓系統體驗變差或不可用。

1. 瀏覽器緩存

1.1 簡述

通過控制響應頭信息,告訴瀏覽器讓其將對應的數據緩存到本地,在指定時間范圍內,可直接從本地緩存中取即可,但瀏覽器方可以不選擇走緩存。

1.2 案例演示

本文中還是使用WebAPI項目進行演示,只是通過不同的API來區分不同案例。

創建好項目中,在默認的WeatherForecastController中添加一個Action方法,如下:

這個時候還沒有做緩存處理,所以只要訪問都會調用接口獲取最新的數據。

在接口方法上只需添加ResponseCache特性就可以實現瀏覽器緩存,如下:

這樣就可以實現客戶端緩存了,可能會有小伙伴會點擊瀏覽器的刷新和F5進行測試,這個時候並沒有看到緩存效果,其實這個時候瀏覽器是以新的請求發出的,並不會去緩存里取,但其實請求獲取到的數據已經存緩存了。

那怎么去測試呢?每次都 打開多個瀏覽器標簽或用Swagger的形式,如下:

第一次訪問:

每次都打開新標簽,再訪問接口:

除了根據數據沒變來判定是緩存數據外,還可以通過請求確定是否從本地緩存中取數據,如下:

Swagger演示,關於如何集成Swagger,之前有專門分享過(跟我一起學.NetCore之Swagger讓前后端不再煩惱及界面自定義):

瀏覽器緩存的原理其實就是在響應頭中增加Cache-Control(ResponseCache的方式是通過Action過濾器的形式設置的響應頭),告訴瀏覽器進行數據緩存,在指定時間范圍內可以從緩存中取,我們也可以自己手動設置響應頭信息來達到同樣的效果,如下:

盡管數據已經緩存,瀏覽器也可以選擇不從緩存取,如下:

2. 服務器緩存

2.1 簡述

瀏覽器緩存只是將數據保存在單台電腦的不同位置,如果打開不同的瀏覽器或不同的電腦訪問時,還是起不到緩存的效果,所以搞個服務器緩存肯定是個不錯的選擇。

將數據緩存到站點服務器中,當請求過來時,如果命中緩存,直接獲取返回即可,不調用對應的后台API

2.2 案例

其實這只是在原來瀏覽器緩存的基礎上增加了一個中間件的處理,如下:

代碼如下:

運行效果:

由於不同的瀏覽器保存的數據位置不一樣,如果僅僅是本地緩存,那么兩個瀏覽器的數據會返回不一樣;另外第一個瀏覽器訪問之后,其他瀏覽器在時間范圍內獲得結果是一樣的,也不會調用后台接口。

這種服務器端的緩存在有些情況是不生效的,如:請求Method不是Get或Head的不緩存,返回狀態碼不是200的不緩存,請求頭包含Authorization的不緩存等,所以基本很少用這種方式進行緩存操作。

3. 應用內存緩存

3.1 簡述

對於上面說到的瀏覽器緩存和服務器緩存,如果是友好的用戶訪問,沒問題,能起到一定的效果;但如果有人要使壞,不設置對應的請求頭訪問API(禁用緩存),最終還是會給應用服務器和數據庫服務器帶來壓力。所以需要一種能主動控制的緩存方式,后端程序就是下手的對象,在后端程序中寫緩存邏輯,這樣緩存策略就由我們自己控制了。

雖然每次請求都會進入應用程序,但會先從緩存中進行獲取數據,如果命中緩存,就不再進行數據庫訪問,直接將緩存數據返回。

3.2 案例

其實框架中針對內存緩存這塊已經做好了封裝,只需注冊相關的服務就可以用了,如下:

注冊完成之后,只需要注入就可以使用了,這里增加一個Action方法進行演示:

效果就不截圖了,在20秒內,單程序部署情況下,不管怎么訪問都會是一樣的結果。如果想更多了解MemoryCache的使用,可以看看這篇文章《因MemoryCache鬧了個笑話》。

4. 分布式緩存

4.1 簡述

內存緩存雖然能解決瀏覽器和服務器緩存的缺點,但只對單體部署程序比較適用,對於需要分布式部署的程序來說,程序內存之間的緩存數據不能共享,緩存的效果肯定就沒那么盡人意,所以分布式緩存就出來了,采用對應的中間件,如Memcache、Redis等,而Redis成為了緩存的首選。

請求的邏輯和內存緩存差不多一樣,只是分布式緩存會采用第三方中間件進行數據存儲,保證分布式部署的程序共用一套緩存。

4.2 案例

這里還是用最火的Redis做演示,所以需要提前安裝Redis,關於Redis系列的文章,小伙伴們可以看這《給我一起學Redis》。

框架也提供了統一操作分布式緩存的接口IDistributedCache,用法和上面的內存緩存基本一樣。

這里用的是Redis,所以需要安裝對應的Nuget包Microsoft.Extensions.Caching.StackExchangeRed,然后注冊相關服務就可以用了,如下:

注冊完成之后,只需要注入就可以使用了,這里也增加一個Action方法進行演示:

訪問對應的接口,在設置的時間范圍內從Redis中讀取到的數據一致,過期之后就會清空,程序又會設置新的值,如下:

關於緩存的幾種用法就先暫時說這么多,也有小伙伴根據業務場景自己實現的。

實例的源碼:https://gitee.com/CodeZoe/dot-net-core-study-demo/tree/main/CacheDemo

總結

緩存之所以現在這么火,其主要目的還是提升數據訪問效率,緩解應用和數據庫的壓力,但同時也會帶來一些問題,比如緩存穿透、緩存擊穿、緩存雪崩及緩存數據與數據庫不一致等問題,后續我們會逐個說說,關注“Code綜藝圈”,和我一起學習吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM