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、使用前置条件