文章目录
- 前言
- 一、什么是缓存
- 二、客户端缓存
- 核心机制:HTTP缓存头
- 1)使用[ResponseCache]属性(推荐)
- 2)预定义缓存配置(CacheProfile)
- 3)手动设置HTTP头
- 4)缓存验证机制(条件请求)
- 三、最佳实践与注意事项
- 适用场景
- 避免的陷阱
- 总结
前言
在 .NET Core 中,缓存是性能优化的重要手段之一。
一、什么是缓存
缓存(Caching)是提升应用性能的关键技术,通过存储频繁访问的数据来减少计算和数据库压力。
数据库中的索引等简单有效的优化功能本质上都是缓存。
二、客户端缓存
客户端Cache-Control:核心指令,定义缓存策略:响应缓存是通过HTTP响应头(如Cache-Control、Expires)告知浏览器或其他客户端缓存资源的机制。它允许客户端(如浏览器)在本地存储资源副本,减少对服务器的重复请求。
核心机制:HTTP缓存头
客户端缓存通过以下HTTP头控制:
- Cache-Control:核心指令,定义缓存策略:
- public:允许代理和客户端缓存资源
- private:仅允许客户端(浏览器)缓存
- max-age=<seconds>:资源有效期(如max-age=3600表示1小时)
- no-cache:每次需向服务器验证资源是否过期(使用ETag或Last-Modified)
- no-store:禁止缓存(如敏感数据)
- Expires:指定资源过期的绝对时间(HTTP/1.0遗留,优先级低于Cache-Control)
- ETag/Last-Modified:验证缓存有效性(服务端返回资源标识,客户端后续请求
携带If-None-Match或If-Modified-Since验证)
1)使用[ResponseCache]属性(推荐)
- 在控制器或Action方法上标记,自动生成缓存头
[HttpGet] [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)] public ActionResult<DateTime> GetNowTime() { return DateTime.Now; //var product = _db.Products.Find(id); //return product ; }
- 参数说明:
Duration:缓存时间(秒)。
Location:缓存位置(Client或Any)。
2)预定义缓存配置(CacheProfile)
- 在Program.cs中定义全局缓存模板,避免重复配置:
builder.Services.AddControllers(options => { options.CacheProfiles.Add("DefaultClientCache", new CacheProfile { Duration = 20, // 20秒 Location = ResponseCacheLocation.Client, VaryByHeader = "User-Agent" }); });
- 在Controller中引用
[ResponseCache(CacheProfileName = "DefaultClientCache")] [HttpGet] public ActionResult<DateTime> GetNowTime() { return DateTime.Now; }
- 参数说明
Location:缓存位置(Client或Any)。
VaryByHeader:根据请求头区分缓存版本(如User-Agent)。
CacheProfileName:引用预定义的缓存配置。
3)手动设置HTTP头
- 直接操作HttpContext.Response.Headers:
[HttpGet] public ActionResult<DateTime> GetNowTime() { Response.Headers.CacheControl = new[] { "public", "max-age=20" }; // 缓存20秒 return DateTime.Now; }
4)缓存验证机制(条件请求)
- 结合ETag或Last-Modified实现高效缓存验证
[HttpGet] public ActionResult<DateTime> GetNowTime() { //Response.Headers.CacheControl = new[] { "public", "max-age=20" }; // 缓存20秒 var etag = Guid.NewGuid().ToString(); // 根据内容生成唯一标识 // 检查客户端是否已有最新版本 if (Request.Headers.IfNoneMatch == etag) { return StatusCode(304); // 304 Not Modified } Response.Headers.ETag = etag; Response.Headers.CacheControl = "public, max-age=5"; return DateTime.Now; }
三、最佳实践与注意事项
适用场景
- 静态资源:如图片、CSS、JS文件(设置长缓存如max-age=31536000)。
- 低频变化的动态数据:如用户公共资料、商品分类。
- 带宽敏感场景:减少重复传输大型资源。
避免的陷阱
-
过度缓存动态数据:导致用户看到过期信息(如实时股价)
方案:使用no-cache或短max-age,结合ETag验证。 -
忽略缓存版本控制:文件更新后客户端未刷新。
方案:为静态资源文件名添加哈希(如app-{hash}.js)。 -
未处理Vary头:不同设备/语言返回相同缓存。
方案:设置VaryByHeader或VaryByQueryKeys。
总结
- 通过合理配置客户端响应缓存,可显著减少服务器负载并提升用户体验。关键点包括:
- 使用[ResponseCache]属性或手动设置Cache-Control头部。
- 结合ETag或Last-Modified实现条件请求。
- 避免对高频变化数据过度缓存,并通过Vary头处理多版本资源。
- 利用浏览器工具和性能监控持续优化缓存策略。