1、前言css
源碼git
一、最近一直在看項目性能優化方式,俗話說的好項目優化第一步那固然是添加緩存,咱們的項目之因此卡的和鬼同樣,要麼就是你的代碼循環查詢數據庫(這個以前在咱們的項目中常常出現,如今慢慢在修正)或者代碼作了不少不應作的事情。這個時候就能夠引入咱們的緩存了。(只要你的代碼不是寫的特別差,好比以前實習的我)。web
二、緩存主要分爲兩種 客戶端(瀏覽器緩存)、服務端緩存。當咱們的數據不須要及時返回的時候,能夠考慮將頁面緩存到客戶的瀏覽器中進行保存,在必定的時間內訪問直接讀取瀏覽器緩存的信息。咱們經過設置HTTP的響應頭 Cache-Control 來完成頁面存儲到瀏覽器緩存中以下所示:
redis
2、客戶端(瀏覽器緩存)數據庫
一、在老的版本的MVC裏面,有一種能夠緩存視圖的特性(OutputCache),能夠保持同一個參數的請求,在N段時間內,直接從mvc的緩存中讀取,不去走視圖的邏輯。瀏覽器
//老版本的.NET 作法 [OutputCache(Duration =20)]//設置過時時間爲20秒 public ActionResult ExampleCacheAction() { var time=DateTime.Now.ToString("yyyy年MM月dd日 HH時mm分ss秒"); ViewBag.time= time; return View(); }
二、在.Net core 中就沒有(OutputCache)了,使用的是(ResponseCache)特性。官方文檔上稱:響應緩存可減小客戶端或代理對 web 服務器的請求數。 響應緩存還可減小量工做的 web 服務器執行程序生成響應。 響應緩存由標頭,指定你但願客戶端、 代理和緩存響應的中間件如何控制。緩存
/* Duration 表明緩存持續時間(秒)至少1秒 VaryByHeader 設置vary 請求頭信息使用vary頭有利於內容服務的動態多樣性。例如,使用Vary: User-Agent頭,緩存服務器須要經過UA判斷是否使用緩存的頁面。 Location 緩存位置 None 報頭設置爲「no-cache」不使用緩存 Client 只緩存在客戶端。設置「Cache-control」標題爲「private」。 Any 緩存在代理和客戶端。設置「Cache-control」標題爲「public」。 NoStore 緩存中不得存儲任何關於客戶端請求和服務端響應的內容。每次由客戶端發起的請求都會下載完整的響應內容。若是設置爲False Duration必須大於0 VaryByQueryKeys 能夠按照相同頁面,不一樣的參數進行相應的存儲 CacheProfileName 設置緩存配置文件的值,能夠經過設置不一樣的緩存參數 */ [ResponseCache(Duration = 50, VaryByQueryKeys = new string[] { "q","name" })] public IActionResult Index(int q,string name) { return View(DateTime.Now); }
三、經過運行咱們能夠看到,瀏覽器多了一個cache-control:public,max-age=50 它的意思是public緩存在代理和客戶端。max-age=50表明緩存的時間50秒。性能優化
四、還有一種簡單粗暴的實現方式,由於咱們知道添加了這個特性只是在響應請求頭中添加了一個cache-control:public,max-age=50,那麼咱們能夠也能夠直接在請求響應中設置這個請求頭就完事了,效果都是同樣的。服務器
public IActionResult Index() { //直接一,簡單粗暴,不要拼寫錯了就好~~ Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.CacheControl] = "public, max-age=600"; //直接二,略微優雅點 //Response.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue() //{ // Public = true, // MaxAge = TimeSpan.FromSeconds(600) //}; return View(); }
五、有時候爲了統一管理緩存配置,咱們能夠將緩存配置提早寫到配置中,使用名字進行調用。[ResponseCache(CacheProfileName ="test")],在Startup中注入視圖的時候寫入。mvc
//設置一些緩存策略 services.AddControllersWithViews(options => { options.CacheProfiles.Add("default", new CacheProfile { Duration = 60 }); options.CacheProfiles.Add("test", new CacheProfile { Duration = 30, Location=ResponseCacheLocation.Client }); });
六、[ResponseCache] 參數
3、服務端緩存
一、ResponseCache也能夠設置服務端緩存,將咱們返回的數據存儲在服務端中在必定的時間內返回存儲的數據,這裏我先引入一個案例,有時候咱們須要傳遞不一樣的參數進行緩存。
案例:當咱們訪問的數據帶分頁參數的時候咱們怎麼作呢?VaryByQueryKeys前面咱們講了這個,能夠根據不一樣的參數進行緩存,那麼咱們如今使用看看 。
結果:當咱們運行的時候,發現報錯了,報錯的意思大體是說咱們沒有使用中間件,可是爲何我這個緩存要使用到中間件呢?實際上是由於要區分,咱們請求的參數,而後會將咱們的數據進行緩存起來,就是實現了服務端緩存。這裏的咱們就要使用微軟提供的中間件了。
二、咱們主要是在Startup中注入services.AddResponseCaching();和app.UseResponseCaching();中間件。服務端緩存能夠緩存頁面數據和API數據,同時若是咱們服務端存在數據,也就是緩存命中的狀況下,會直接從緩存中取,不會再進入咱們的方法。
public void ConfigureServices(IServiceCollection services) { services.AddResponseCaching(options => { options.UseCaseSensitivePaths = false; options.MaximumBodySize = 1024; options.SizeLimit = 100 * 1024*1024; }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseResponseCaching(); }
服務端緩存配置以下,當咱們配置添加了中間件和注入緩存以後,就可使用VaryByQueryKeys了。當咱們訪問一次以後就會將結果緩存到咱們的客戶端緩存中,和服務端緩存各一份。當咱們使用同一個瀏覽器訪問的時候訪問的就是客戶端緩存信息,當咱們切換瀏覽器訪問的時候也不會請求咱們的方法,會先進入到咱們的中間件中查看是否存在服務端緩存,若是存在就是直接拿緩存進行返回,若是沒有就會請求方法返回,而後再將結果進行緩存。
屬性 |
描述 |
---|---|
MaximumBodySize |
響應正文的最大可緩存大小(以字節爲單位)。 默認值爲 64 * 1024 * 1024 (64 MB)。 |
SizeLimit |
響應緩存中間件的大小限制(以字節爲單位)。 默認值爲 100 * 1024 * 1024 (100 MB)。 |
UseCaseSensitivePaths |
肯定是否將響應緩存在區分大小寫的路徑上。 默認值是 false。 |
三、對於一些常年不變或比較少變的js,css等靜態文件,也能夠把它們緩存起來,避免讓它們老是發起請求到服務器,並且這些靜態文件能夠緩存更長的時間!若是已經使用了CDN,這一小節的內容就能夠暫且忽略掉了。。。對於靜態文件,.NET Core有一個單獨的StaticFiles中間件,若是想要對它作一些處理,一樣須要在管道中進行註冊。UseStaticFiles
有幾個重載方法,這裏用的是帶StaticFileOptions參數的那個方法。由於StaticFileOptions裏面有一個OnPrepareResponse可讓咱們修改響應頭,以達到HTTP緩存的效果。
app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = context => { context.Context.Response.GetTypedHeaders().CacheControl = new Microsoft.Net.Http.Headers.CacheControlHeaderValue { Public = true, //for 1 year MaxAge = System.TimeSpan.FromDays(365) }; } });
4、使用前置條件