什么是缓存
缓存(Caching)是系统优化中简单又有效的工具,投入小收效大。数据库中的索引等简单有效的优化功能本质上都是缓存。
缓存的概念
1、缓存命中
2、缓存命中率
3、缓存数据不一致
多级缓存(浏览器中可能也有缓存)
ASP.NET Core客户端响应缓存
cache-control
1、RFC7324是HTTP协议中对缓存进行控制的规范,其中重要的是cache-control这个响应报文头。服务器如果cache-control:max-age=60,则表示服务器指示浏览器端"可以缓存这个响应内容60秒"
2、我们只要给需要进行缓存控制的控制器的操作方法添加ResponseCacheAttribute这个Attribute,ASP.NET Core会自动添加cache-control报文头
3、验证:编写一个返回当前时间的Action方法。分别加和不加ResponseCacheAttribute看区别。也F12看看Network
4、缺点:各个浏览器缓存是相互独立的,每个浏览器都得请求一遍服务器端,再进行缓存,缓存不共享
[ResponseCache(Duration = 20)]
[HttpGet]
public DateTime Now()
{
return DateTimie.Now;
}
ASP.NET Core服务端响应缓存
Response Caching Middleware
1、如果ASP.NET Core中安装了“响应缓存中间件”,那么ASP.NET Core不仅会继续根据[ResponseCache]设置来生成cache-control响应报文头来设置客户端缓存,而且服务器端也会按照[ResponseCache]的设置来对响应进行服务器端缓存。和客户端缓存的区别?来自多个不同客户端的相同请求。
2、“响应缓存中间件”的好处:对于来自不同客户端的相同请求或者不支持客户端缓存的客户端,能降低服务器端的压力。
3、用法:app.MapControllers()之前加上app.UseResponseCaching()。请确保app.UseCors()写到app.UseResponseCacheing()之前
演示效果
1、大部分浏览器都是支持RFC7324规范的,所以不方便用来测试服务端响应缓存。用默认忽略RFC7324规范的PostMan测试。试一下请求服务器端
2、可以在浏览器的“开发人员工具”中禁用缓存,但是和PostMan中不一致,为什么?“cache-control:no-cache”
3、也可以让PostMan在请求报文头中加如“cache-control:no-cache”,只要在Postman的设置中开启【Send no-cache headers】
服务器端响应缓存的缺点
1、无法解决恶意请求给服务器带来的压力
2、服务器端响应缓存还有很多限制,包括但不限于:响应状态码为200的Get或者HEAD请求才可能被缓存;报文头中不能含有Authorization、Set-Cookie等。
Authorization为什么?:把一个浏览器响应的具体用户数据的缓存下来,给到另外一个用户浏览器不现实
3、不怪他,honor RFC7234.It's a feature,not a bug
4、怎么办呢?采用内存缓存、分布式缓存等
ASP.NET Core中的内存缓存
内存缓存
1、把缓存数据放到应用程序的内存。内存缓存中保存的是一系列的键值对,就像Dictionaty类型一样
2、内存缓存的数据保存再当前运行的网站程序的内存中,是和进程相关的。因为再Web服务器中,多个不同的网站时运行在不同的进程中的,因此不同网站的内存缓存是不会互相干扰的,而且网站重启后,内存缓存中所有数据也就都被清空了。
内存缓存的用法
1、启用:builder.Service.AddMemoryCache()
2、注入IMemoryCache接口,查看接口的方法:TryGetValue、Remove、Set、GetOrCreate、GetOrCreateAsync
3、一般情况下都是使用GetOrCreateAsync,用起来比较方便,代码如下
public async Task<Book[]> GetBooks()
{
logger.LogInformation("开始执行GetBooks");
var items = await memCache.GetOrCreateAsync("AllBooks", async (e) =>
{
logger.LogInformation("从数据库中读取数据");
return await dbCtx.Books.ToArrayAsync();
});
logger.LogInformation("把数据返回给调用者");
return items;
}