一、HTTP响应缓存报文头 cache-control
1.RFC7324是HTTP协议中对缓存进行控制的规范,其中重要的是cache-control这个响应报文头。服务器如果返回cache-control:max-age=60,则表示服务器指示浏览器端“可以缓存这个响应内容60秒”。
2.客户端响应缓存:
给要进行缓存控制的控制器的操作方法添加ResponseCacheAttribute这个特性,ASP.NET Core会自动添加cache-control报文头。
[ResponseCache(Duration=20)]
[HttpGet]
public string TestMethod()
{
}
3. ASP.NET Core服务端响应缓存:Response Caching Middleware(响应缓存中间件)
1)如果ASP.NET Core安装了“响应缓存中间件”,那么ASP.NET Core不仅会根据ResponseCacheAttribute生成响应报文头设置客户端缓存,而且服务器端也会据此来进行服务器端缓存。
2)“响应缓存中间件”的好处:对于来自不同客户端的相同请求或者不支持客户端缓存的客户端,能降低服务器端压力。
3)用法:app.MapControllers()之前加上app.UseResponseCaching(),确保app.UseCors()写到app.UseResponseCaching()之前。
app.UseCors();
app.UseResponseCaching();
app.MapControllers();
4.使用cache-control的问题是:
1)浏览器等客户端可以不遵从报文头缓存建议,例如禁用缓存。
2)服务端响应缓存并不具备强制性,例如客户端请求时报文头设置:Cache-2.Control:no-cache。此时,服务端缓存设置将被忽略。
3)服务端响应缓存还有很多限制,包括但不限于:响应状态码为200的GET或者HEAD响应才能被缓存;报文头中不能包含有Authorization、Set-Cookie等。
5.结论:
不推荐使用,使用内存缓存、分布式缓存解决。
二、内存缓存(In-memory Cache)
1.定义:把缓存数据放到应用程序的内存。保存的是键值对,就像Dictionary类型一样。
2.特点:数据保存在程序的内存中,和进程相关。不同网站的内存缓存不会互相干扰,网站重启后,数据清空。
3.在APS.NET Core 启用方法:
1)在Program.cs的启动方法中,添加builder.Services.AddMemoryCache();
2)在需要使用的控制器中,注入IMemoryCache接口;
3)使用GetOrCreateAsync方法。
4.缓存的过期时间策略:
1)在数据改变时调用Remove或者Set方法修改缓存(优点:及时);
2)设置过期时间,有两种过期时间类型:绝对过期时间,滑动过期时间。一般设置绝对过期时间就足够。滑动过期时间一般不单独使用,以避免频繁的请求导致缓存一直不能刷新。两者可结合使用。
5.优缺点:
效率高,但无法跨应用、服务器集群复用缓存。
6.结论:
推荐使用,大部分情况下够用,实在不够,再用分布式缓存。
三、分布式缓存
1.描述:在分布式系统中,如果集群节点数量非常多的话,重复查询同样可能把数据库压垮。此时使用分布式缓存服务器。
2.常用的分布式缓存服务器:Redis、Mecached等。
3..Net Core中提供了统一的分布式缓存服务器操作接口IDistributedCache,用法和内存缓存类似。
4.分布式缓存与内存缓存的区别:缓存值的类型为byte[],需要我们进行类型转换。也提供了一些按照string类型存取的扩展方法。
5.ASP.NET Core中Redis分布式缓存用法:
1)NuGet安装Microsoft.Extensions.Caching.StackExchangeRedis;
2)在Program.cs的启动方法中,添加如下代码:
builder.Services.AddStackExchangeRedisCache(opt =>
{
opt.Configuration = "localhost";
opt.InstanceName = "cache_";
});
3)在需要使用的控制器中,注入IDistributedCache,使用相应方法。
四、缓存穿透问题
1.使用内存缓存时,使用GetOrCreateAsync方法可以避免缓存穿透问题。
2.使用分布式缓存时,Redis有避免缓存穿透的机制。
五、缓存雪崩问题
缓存项集中过期引起缓存雪崩。
解决方法:在基础过期时间上,加上一个随机的过期时间。