前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET Core ResponseCache进行缓存操作

ASP.NET Core ResponseCache进行缓存操作

作者头像
HueiFeng
发布2020-02-27 14:38:29
2.9K0
发布2020-02-27 14:38:29
举报

前言

本章将介绍客户端缓存将介绍浏览器缓存和服务端缓存,使用浏览器缓存将减少对web服务器的请求次数,同时可以提升性能,避免重复的运算浪费。

ASP.NET Core对于HTTP缓存分为两种:

  • 客户端(浏览器缓存)
  • 服务端缓存

客户端缓存

通过设置HTTP的响应头 Cache-Control 来完成页面存储到浏览器缓存中如下所示:

客户端缓存示意图
客户端缓存示意图

其实客户端缓存的话只需要进行设置 ResponseCache 特性就可以请看如下代码片段

[ResponseCache(Duration = 100,Location = ResponseCacheLocation.Client)]
public IActionResult Index()
{
      return View();
}

ResponseCacheAttribute 可应用于:

  • Razor 页面处理程序(类) – 特性不能应用于处理程序方法。
  • MVC 控制器(类)。
  • MVC 操作(方法) – 方法级特性覆盖类级特性中指定的设置。

[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 设置缓存配置文件的值,可以通过设置不同的缓存参数

CacheProfileName使用请看如下代码片段

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews(options =>
            {
                options.CacheProfiles.Add("default", new CacheProfile
                {
                    Duration = 60
                });

                options.CacheProfiles.Add("test", new CacheProfile
                {
                    Duration = 30
                });
            });
        }

上述代码我们设置好了两份不一样的配置,那么我们就可以通过下面代码片段进行使用了

    [ResponseCache(CacheProfileName = "default")]
    public IActionResult Index()
    {
         return View();
   }

服务端缓存

服务端缓存可以缓存页面数据和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();
        }

服务端缓存配置如下

属性

描述

MaximumBodySize

响应正文的最大可缓存大小(以字节为单位)。 默认值为 64 * 1024 * 1024 (64 MB)。

SizeLimit

响应缓存中间件的大小限制(以字节为单位)。 默认值为 100 * 1024 * 1024 (100 MB)。

UseCaseSensitivePaths

确定是否将响应缓存在区分大小写的路径上。 默认值是 false。

        [ResponseCache(Duration = 30, VaryByQueryKeys = new[] { "q" })]
        public IActionResult Index(int q)
        {
            _logger.LogWarning($"我是一个路径:{HttpContext.Request.Host}");
            return View(model:DateTime.Now.ToString());
        }

VaryByQueryKeys

使用 MVC/web API 控制器或 Razor Pages 页面模型时, [ResponseCache]属性指定为响应缓存设置适当的标头所需的参数。 严格需要中间件的 [ResponseCache] 属性的唯一参数 VaryByQueryKeys,这与实际 HTTP 标头不对应。 有关详细信息,请参阅 响应缓存在 ASP.NET Core。 如果不使用 [ResponseCache] 属性,响应缓存可能会与 VaryByQueryKeys不同。 我们再看看如上代码效果

ResponseCache中间件使用的 HTTP 标头

响应头

描述

Authorization

如果标头存在,则不会缓存。

Cache-Control

中间件仅考虑用 public 缓存指令标记的缓存响应。

Pragma

请求中的 Pragma: no-cache 标头将产生与 Cache-Control: no-cache相同的效果。 如果存在此标头,则由 Cache-Control 标头中的相关指令重写。 考虑向后兼容 HTTP/1.0。

Set-Cookie

如果标头存在,则不会缓存响应。 请求处理管道中设置一个或多个 cookie 的任何中间件会阻止响应缓存中间件缓存响应(例如,基于 cookie 的 TempData 提供程序)。

Vary

Vary 标头用于根据另一个标头改变缓存的响应。 例如,通过编码来缓存响应,包括 Vary: Accept-Encoding 响应头,该响应头将缓存标头为 Accept-Encoding: gzip 和 Accept-Encoding: text/plain 的请求的响应。 永远不会存储响应头值为 * 的响应。

Expires

除非被其他 Cache-Control 标头重写,否则不会存储或检索此响应头过时的响应。

If-None-Match

如果值不为 *,响应的 ETag 与提供的任何值都不匹配,则将从缓存中提供完整响应。 否则,将提供304(未修改)响应。

If-Modified-Since

如果 If-None-Match 标头不存在,则在缓存的响应日期比提供的值更新时,将从缓存中提供完整响应。 否则,将提供304-未修改响应

Date

从缓存提供时,如果未在原始响应中提供,则中间件会设置 Date 标头。

Content-Length

从缓存提供时,如果未在原始响应中提供,则中间件会设置 Content-Length 标头。

Age

忽略原始响应中发送的 Age 标头。 中间件在为缓存的响应提供服务时计算一个新值。

缓存条件

  • 请求必须导致服务器响应,状态代码为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” 指令。

Reference

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-3.1

https://github.com/hueifeng/BlogSample/tree/master/src/ResponseCachingDemo

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档