性能优化万金油:缓存

本文介绍缓存的概念及其在Web开发中的应用,涵盖客户端与服务器端缓存控制,并探讨ASP.NET Core中的缓存策略,包括响应缓存Attribute及响应缓存中间件的使用。

性能优化万金油:缓存

1.什么是缓存

缓存是一个用来保存数据的区域,从缓存区域中读取数据的速度比从数据源读取数据的速度快很多。在从数据源(如数据库)获取数据之后,我们可以把数据保存到缓存中,如下图所示。下次再需要获取同样数据的时候,我们可以直接从缓存中获取之前保存的数据,而不需要再去数据源获取数据

在这里插入图片描述

由于从缓存中读取数据的速度比从数据源中读取数据的速度更快,因此使用缓存能提高系统数据的获取速度…

  1. 缓存击中
    1. 从缓存中获取了想要的数据
  2. 命中率
    1. 多次请求中,命中的请求占全部请求的百分比
  3. 缓存数据不一致
    1. 数据源中的数据保存到缓存中后,发生了变化

多级缓存

  • 在Web开发中,存在着多级缓存,比如在浏览器端存在**“浏览器缓存”**
  • 在网关节点服务器也可能存在**”节点缓存“**
  • 在Web服务器上也可能存在**”服务器端缓存“**

HTTP中的RFC 7234规范中对缓存处理进行了规定,如果客户端(浏览器、App、物联网终端等)、CDN节点、API网关节点服务器、反向代理服务器、Web服务器等遵守这个规范,它们就会按照缓存相关的报文头中的设置对缓存进行控制。ASP.NET Core 中的响应缓存(response caching)就是遵守RFC 7234规范的缓存控制机制,它可以对浏览器缓存、CDN节点缓存、服务器端缓存进行统一的控制。
RFC 7234规范对缓存的控制有一定的局限性,因此有时候我们需要进行更加个性化的服务器端缓存控制。ASP.NET Core 不仅提供了把Web 服务器的内存用作缓存的内存缓存(in-memory cache),还提供了把Redis、数据库等用作缓存的分布式缓存(distributed cache)。

2.客户端响应缓存

RFC 7234是 HTTP中对缓存进行控制的规范,其中重要的是cache-control响应报文头。假如浏览器向服务器请求/api/Test/Now 这个路径,如果服务器端给浏览器端的响应报文头中cache-control的值为max-agmax-age=20,,则表示服务器指示浏览器端可以缓存这个响应内容20s”。在60s内,如果用户要求浏览器再次向/api/Test/Now发送请求的话,浏览器就可以直接使用保存的缓存内容,而不是向服务器再次发出请求。
在ASP.NET Core中,我们一般不需要手动控制响应报文头中的cache-control,只要给需要进行缓存控制的控制器的操作方法添加ResponseCacheAttribute这个Attribute 即可,ASP.NETCore会根据 ResponseCacheAttribute的设置来生成合适的cache-control响应报文头。

现在我们来测试一下

    public class TestController : ControllerBase
    {
        //加上ResponseCacheAttribute,设置为20秒
        [ResponseCache(Duration = 20)]
        [HttpGet]
        public DateTime Now()
        {
            return DateTime.Now;
        }
    }

好,启动!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AWHo5B3R-1672317268366)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221229194444299.png)]

这是第一次发起请求,我们可以看到Response Headers中的max-age=20,浏览器会把这个响应内容缓存20S

下面我们来发起第二次请求(这里由于20S过了,又发起了一次)

在这里插入图片描述

现在可以看到Size中显示的是disk cache磁盘缓存,表示我们这次请求的响应是直接从浏览器缓存中获取的,而且内容一样
在这里插入图片描述

默认情况下,[ResponseCache]设置只通过生成 cache-control 响应报文头来控制客户端缓存。如果客户端不支持客户端缓存,这个设置也是不生效的,毕竟是否使用缓存、如何使用缓存都是由客户端决定的,cache-control响应报文头只是一个“建议”而已。

3.服务器端响应缓存

如果我们在ASP.NET Core中安装了“响应缓存中间件”(response caching middleware),ASP.NET Core 不仅会继续根据[ResponseCache]设置来生成cache-control响应报文头以设置客户端缓存,还会在服务器端也按照[ResponseCache]的设置来对响应进行服务器端缓存。

如果没有启用“响应缓存中间件”,那么当A、B、C这3个浏览器分别向/Testl/Now路径发送请求的时候,服务器端的Now方法会执行3次;如果启用了“响应缓存中间件”,当A、B、C这3个浏览器分别向/Testl/Now路径发送请求的时候,只要后面两次请求的时间在60s内,服务器端的Now方法只会执行1次,后两次请求虽然也会到达服务器,但是服务器会把第1次响应的缓存内容直接返回,而不会执行Now方法。
很显然,使用响应缓存中间件在服务器端实现响应缓存有两个好处

  • 第一,提升没有实现缓存机制的客户端获取数据的速度,因为虽然请求仍然到达了服务器,但服务器端缓存直接返回了缓存的响应,避免了从执行速度缓慢的数据源获取数据的性能问题
  • 第二,对于实现了缓存机制的客户端也能降低服务器端的压力,因为如果没有启用响应缓存中间件,那么如果在短时间内服务器端收到了来自一万个不同客户端到/Test/Now的请求,那么Now方法仍然会执行一万次,因为客户端的缓存是由每个客户端自己管理的
  • 如果启用了响应缓存中间件,Now方法只会执行一次,这降低了服务器端的压力。

启用响应缓存中间件的步骤很简单,除了给控制器中需要进行缓存控制的操作方法标注[ResponseCache]之外,我们只需要在ASP.NET Core项目的Program.csapp.MapControllers之前加上app.UseResponseCaching即可

不过需要注意的是,如果项目启动跨域CORS,要确保app.UseCors写到app.UseResponseCaching之前

现在,让我们开启服务器端缓存,试试效果
在这里插入图片描述

使用不同的浏览器来模拟不同的客户端,浏览器之间的缓存也是不共享的

这是Chrome

在这里插入图片描述

这是Edge

在这里插入图片描述

同时发起请求!

在这里插入图片描述

结果正如上所说

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGkClmPu-1672317268374)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221229200607470.png)]

在第一个浏览器发起请求后,服务器配置了[ResponseCaching]已经开启了服务器缓存,会自动缓存一份响应结果,在这个响应结果失效之前,任何发起相同请求的浏览器都会从服务器缓存中获取响应结果,这样在访问量比较大的情况下,会大大减轻服务器的压力。

但是服务器端响应缓存是比较鸡肋的
1、无法解决恶意请求服务器带来的压力。
2、服务器端响应缓存还有很多限制,包括但不限于:响应状态码为200的GET或者HEAD响应才可能被缓存;报文头中不能含有Authorization、Set-Cookie?等。

大部分浏览器是支持RFC 7234规范的,在Chrome等浏览器中,当我们禁用了浏览器缓存后,不仅浏览器本地会忽略cahce-control而禁用所有的客户端缓存,而且浏览器还会在向服务器端发送的请求的时候,在请求的报文头中加入cache-control: no-cache,这个报文头用来告知服务器禁用缓存,这样服务器端的缓存机制也会被禁用,这是RFC 7234规范要求的

这就会导致,我们禁用了浏览器端的缓存后,服务器端响应缓存也会失效

至于无法解决恶意请求服务器是因为,它可以在请求头中加入cache-control: no-cache,这样就会轻易的突破服务器端响应缓存,相当于裸奔了,这样就可以进行恶意请求,有的请求会消耗大量性能,这样会给服务器带来很大的压力…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栀梦星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值