.NET Core ResponseCache【缓存篇(一)】
一、前言
1、最近一直在看项目性能优化方式,俗话说的好项目优化第一步那当然是添加缓存,我们的项目之所以卡的和鬼一样,要么就是你的代码循环查询数据库(这个之前在我们的项目中经常出现,现在慢慢在修正)或者代码做了很多不该做的事情。这个时候就可以引入我们的缓存了。(只要你的代码不是写的特别差,比如之前实习的我)。
2、缓存主要分为两种 客户端(浏览器缓存)、服务端缓存。当我们的数据不需要及时返回的时候,可以考虑将页面缓存到客户的浏览器中进行保存,在一定的时间内访问直接读取浏览器缓存的信息。我们通过设置HTTP的响应头 Cache-Control 来完成页面存储到浏览器缓存中如下所示:
二、客户端(浏览器缓存)
1、在老的版本的MVC里面,有一种可以缓存视图的特性(OutputCache),可以保持同一个参数的请求,在N段时间内,直接从mvc的缓存中读取,不去走视图的逻辑。
- //老版本的.NET 做法
- [OutputCache(Duration =)]//设置过期时间为20秒
- public ActionResult ExampleCacheAction()
- {
- var time=DateTime.Now.ToString("yyyy年MM月dd日 HH时mm分ss秒");
- ViewBag.time= time;
- return View();
- }
2、在.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 = , VaryByQueryKeys = new string[] { "q","name" })]
- public IActionResult Index(int q,string name)
- {
- return View(DateTime.Now);
- }
3、通过运行我们可以看到,浏览器多了一个cache-control:public,max-age=50 它的意思是public缓存在代理和客户端。max-age=50代表缓存的时间50秒。
4、还有一种简单粗暴的实现方式,因为我们知道添加了这个特性只是在响应请求头中添加了一个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();
- }
5、有时候为了统一管理缓存配置,我们可以将缓存配置提前写到配置中,使用名字进行调用。[ResponseCache(CacheProfileName ="test")],在Startup中注入视图的时候写入。
- //设置一些缓存策略
- services.AddControllersWithViews(options =>
- {
- options.CacheProfiles.Add("default", new CacheProfile
- {
- Duration =
- });
- options.CacheProfiles.Add("test", new CacheProfile
- {
- Duration = ,
- Location=ResponseCacheLocation.Client
- });
- });
6、[ResponseCache] 参数
- Duration 设置缓存的存储时间(以秒为单位)。设置“Cache-control”中的“max-age”。
- Location
- Any 缓存在代理和客户端。设置“Cache-control”标题为“public”。
- Client 只缓存在客户端。设置“Cache-control”标题为“private”。
- None 每次有请求发出时,缓存会将请求发到服务器 ,服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。 报头设置为“no-cache”。
- NoStore 缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。
- VaryByHeader 使用vary头有利于内容服务的动态多样性。例如,使用Vary: User-Agent头,缓存服务器需要通过UA判断是否使用缓存的页面。
- VaryByQueryKeys 可以按照相同页面,不同的参数进行相应的存储
- CacheProfileName 设置缓存配置文件的值,可以通过设置不同的缓存参数
三、服务端缓存
1、ResponseCache也可以设置服务端缓存,将我们返回的数据存储在服务端中在一定的时间内返回存储的数据,这里我先引入一个案例,有时候我们需要传递不同的参数进行缓存。
案例:当我们访问的数据带分页参数的时候我们怎么做呢?VaryByQueryKeys前面我们讲了这个,可以根据不同的参数进行缓存,那么我们现在使用看看 。
结果:当我们运行的时候,发现报错了,报错的意思大致是说我们没有使用中间件,但是为什么我这个缓存要使用到中间件呢?其实是因为要区分,我们请求的参数,然后会将我们的数据进行缓存起来,就是实现了服务端缓存。这里的我们就要使用微软提供的中间件了。
2、我们主要是在Startup中注入services.AddResponseCaching();和app.UseResponseCaching();中间件。服务端缓存可以缓存页面数据和API数据,同时如果我们服务端存在数据,也就是缓存命中的情况下,会直接从缓存中取,不会再进入我们的方法。
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddResponseCaching(options =>
- {
- options.UseCaseSensitivePaths = false;
- options.MaximumBodySize = ;
- options.SizeLimit = * *;
- });
- }
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- app.UseResponseCaching();
- }
服务端缓存配置如下,当我们配置添加了中间件和注入缓存之后,就可以使用VaryByQueryKeys了。当我们访问一次之后就会将结果缓存到我们的客户端缓存中,和服务端缓存各一份。当我们使用同一个浏览器访问的时候访问的就是客户端缓存信息,当我们切换浏览器访问的时候也不会请求我们的方法,会先进入到我们的中间件中查看是否存在服务端缓存,如果存在就是直接拿缓存进行返回,如果没有就会请求方法返回,然后再将结果进行缓存。
属性 |
描述 |
---|---|
MaximumBodySize |
响应正文的最大可缓存大小(以字节为单位)。 默认值为 64 * 1024 * 1024 (64 MB)。 |
SizeLimit |
响应缓存中间件的大小限制(以字节为单位)。 默认值为 100 * 1024 * 1024 (100 MB)。 |
UseCaseSensitivePaths |
确定是否将响应缓存在区分大小写的路径上。 默认值是 false。 |
3、对于一些常年不变或比较少变的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()
- };
- }
- });
四、使用前置条件
- 请求必须导致服务器响应,状态代码为200(正常)。
- 请求方法必须为 GET 或 HEAD。
- 在 Startup.Configure中,响应缓存中间件必须置于需要缓存的中间件之前。
- Authorization 标头不得存在。
- Cache-Control 标头参数必须是有效的,并且响应必须标记为 “public” 且未标记为 “private”。
- 如果 Cache-Control 标头不存在,则 Pragma: no-cache 标头不得存在,因为 Cache-Control 标头在存在时将覆盖 Pragma 标头。
- Set-Cookie 标头不得存在。
- Vary 标头参数必须有效且不等于 *。
- Content-Length 标头值(如果已设置)必须与响应正文的大小匹配。
- 不使用 IHttpSendFileFeature。
- Expires 标头和 max-age 和 s-maxage 缓存指令指定的响应不能过时。
- 响应缓冲必须成功。 响应的大小必须小于配置的或默认 SizeLimit。 响应的正文大小必须小于配置的或默认的 MaximumBodySize。
- “请求” 或 “响应” 标头字段中不得存在 “no-store” 指令。
.NET Core ResponseCache【缓存篇(一)】的更多相关文章
- .NET Core 的缓存篇之MemoryCache
前言 对于缓存我们都已经很熟悉了,缓存分为很多种,浏览器缓存.试图缓存.服务器缓存.数据库缓存等等一些,那今天我们先介绍一下视图缓存和MemoryCache内存缓存的概念和用法: 视图缓存 在老的版本 ...
- .Net Core缓存组件(MemoryCache)【缓存篇(二)】
一.前言 .Net Core缓存源码 1.上篇.NET Core ResponseCache[缓存篇(一)]中我们提到了使用客户端缓存.和服务端缓存.本文我们介绍MemoryCache缓存组件,说到服 ...
- 讨论过后而引发对EF 6.x和EF Core查询缓存的思考
前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...
- AspnetCore 缓存篇
AspnetCore 缓存篇 一.缓存的作用 怎样理解缓存: 其实所有的程序,架构,优化,线程...等技术手段,最终的目的都是如何使产品快速的响应用户的操作,提高用户的体验性,目标都是为了系统的使用者 ...
- .NET Core C# 中级篇2-7 文件操作
.NET Core CSharp 中级篇2-7 本节内容为文件操作 简介 文件操作在我们C#里还是比较常见的,例如我们读取Excel.Txt文件的内容,在程序中,这些文件都是以流的方式读取进入我们内存 ...
- jQuery2.x源码解析(缓存篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...
- 缓存篇(Cache)~大话开篇
回到占占推荐博客索引 闲话杂淡 想写这篇文章很久了,但总是感觉内功还不太够,总觉得,要写这种编程领域里的心法(内功)的文章,需要有足够的实践,需要对具体领域非常了解,才能写出来.如今,感觉自己有写这种 ...
- 缓存篇(Cache)~第一回 使用static静态成员实现服务器端缓存(导航面包屑)
返回目录 今天写缓存篇的第一篇文章,在写完目录后,得到了一些朋友的关注,这给我之后的写作带来了无穷的力量,在这里,感谢那几位伙伴,哈哈! 书归正传,今天我带来一个Static静态成员的缓存,其实它也不 ...
- 缓存篇(Cache)~第三回 HttpModule实现网页的文件级缓存
返回目录 再写完缓存篇第一回之后,得到了很多朋友的好评和来信,所以,决定加快步伐,尽快把剩下的文章写完,本篇是第三回,主要介绍使用HttpModule实现的文件级缓存,在看本文之前,大家需要限度Htt ...
- 缓存篇~第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存
返回目录 这一讲中主要是说EnterpriseLibrary企业级架构里的caching组件,它主要实现了项目缓存功能,它支持四种持久化方式,内存,文件,数据库和自定义,对于持久化不是今天讨论的重要, ...
随机推荐
- 08.DRF-反序列化
三.反序列化使用 3.1 验证 使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象. 在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功 ...
- linux环境下安装git(采用github下载git源码编译)
[目的]:linux环境下 安装配置git成功 [准备条件]linux系统,git包 1.先行下载git包 -- 从github上https://github.com/git/git/releases ...
- [ C++ ] 勿在浮沙筑高台 —— 内存管理(9~16p)primitives(下)
per-class allocator 2 tips: operator new重载 不会被派生类实际使用,因为父类大小内存的分配交给子类去调用明显是不正确的.实际上会被转交至 : : operato ...
- 一个比CBitmap更优秀的类 -- CImage类
Visual C++的CBitmap类的功能是比较弱的,它只能显示出在资源中的图标.位图.光标以及图元文件的内容,而不像VB中的Image控件可以显示出绝大多数的外部图像文件(BMP.GIF.JPEG ...
- \\u4e00-\\u9fa5\
select * from stu where name regexp '[\\u4e00-\\u9fa5\·]{2,10}$'; 结果: name这个字段从后到前 2 到10个字符之内 如果有汉字 ...
- vs2013, EF6.0.0.0 使用Migrations来更新数据库时报错
1.vs中,程序包管理器控制台 2.执行,Enable-Migrations 报错: Migrations have already been enabled in project 'dd'. To ...
- Centos 6.4 安装KSnapshot 和gimp截图工具
一. # wget http://www.ibiblio.org/pub/Linux/X11/xutils/ksnapshot-0.2.7.tar.gz # tar -zxvf ksnapshot-0 ...
- CentOS/RHEL 6.4/5.9 安装 Adobe Flash Player 11.2
1.root登录: $ su 2.安装 Adobe YUM Repository RPM package X86_64 ________________________________________ ...
- 解读 java 并发队列 BlockingQueue
点击添加图片描述(最多60个字)编辑 今天呢!灯塔君跟大家讲: 解读 java 并发队列 BlockingQueue 最近得空,想写篇文章好好说说 java 线程池问题,我相信很多人都一知半解的,包括 ...
- Meta标签大全_web开发常用meta整理
meta标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 web 服务. 必要属性 属性 值 描 ...