千家信息网

.NET 6开发中怎么实现缓存

发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,小编今天带大家了解.NET 6开发中怎么实现缓存,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习
千家信息网最后更新 2025年11月17日.NET 6开发中怎么实现缓存

小编今天带大家了解.NET 6开发中怎么实现缓存,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习".NET 6开发中怎么实现缓存"的知识吧。


    需求

    有的时候为了减少客户端请求相同资源的逻辑重复执行,我们会考虑使用一些缓存的方式,在.NET 6中,我们可以借助框架提供的中间件来实现请求资源的缓存。

    目标

    实现请求结果的缓存。

    原理与思路

    对于在.NET6中实现缓存,我们可以使用响应缓存中间件ResponseCaching来实现,同时可以使用Marvin.Cache.Headers来为我们提供更多的缓存相关的属性。

    实现

    使用原生ResponseCaching实现缓存

    既然是中间件,我们便在Program中引入:

    Program.cs

    // 省略其他...// 配置缓存中间件builder.Services.AddResponseCaching();builder.Services.AddControllers();// ...// 使用缓存中间件app.UseResponseCaching();app.MapControllers();

    在使用方法上,有几种方式可以实现配置:1)进行全局的配置,应用于所有添加了相同ProfileNameResponseCache的Controller响应;2)对单个Controller/Action进行配置,应用于当前作用的Controller/Action;3)全局配置后,由单个Controller/Action覆盖全局配置。我们会演示1)和3)的场景。

    我们准备使用获取所有TodoLists的接口进行演示。

    先看如何进行全局配置:

    Program.cs

    // 省略其他...builder.Services.AddControllers(options =>{    options.CacheProfiles.Add("60SecondDuration", new CacheProfile { Duration = 60 });});

    验证1: 全局配置Caching

    首先给我们要进行验证的Action添加属性:

    TodoListController.cs

    // 省略其他...[HttpGet][ResponseCache(CacheProfileName = "60SecondDuration")]public async Task>> Get(){    return ApiResponse>.Success(await _mediator.Send(new GetTodosQuery()));}

    启动Api项目,第一次执行获取TodoLists的请求:

    请求

    响应

    响应头中多了一个cache-control字段用于指明缓存的类型(public)以及过期时间为60s:

    如果你是使用Postman或者Insomia发送的请求,那么在过期前再次发起相同请求的返回头中会再多出一个Age字段,用于表明该资源当前缓存了多少秒(Hoppscotch我没找到可以在哪里设置,所以下面的截图是来自Insomia,如果有哪位老哥知道的可以教一下):

    同时如果观察日志的话会发现,第二次请求并没有实际执行SQL语句,这也证明了第二次请求的返回来自缓存:

    如果间隔60s以上我们再去发送相同的请求,会发现日志中是这样的:

    可以看到缓存已经失效了,此时需要重新向数据库查询返回数据,并将这次请求结果缓存起来。

    验证2: 单个Action覆盖全局配置

    我们还是使用这个接口,但是修改一下属性:

    TodoListController.cs

    [HttpGet][ResponseCache(Duration = 120)]public async Task>> Get(){    return ApiResponse>.Success(await _mediator.Send(new GetTodosQuery()));}

    重新启动Api项目,第一次执行获取TodoLists的请求,请求和验证1相同,我们来看响应中的变化:

    响应

    可以看到失效时间已经变为120s了,其他不再一一验证。

    使用Marvin.Cache.Headers实现更多缓存功能

    在缓存中还有一个问题是,如果判断缓存的数据内容已经变化,就需要去获取最新的响应而不是直接从缓存中取值。这是借助缓存校验来完成的,而常使用的方式是通过Etag实现。示意的过程如下:

    如果首次请求资源,API会在响应头中添加EtagLast-Modified字段:

    当客户端再次请求资源时,由于缓存自身是不知道资源有没有被修改,所以缓存会携带If-None-Match字段(和客户端收到的Etag值相等)和If-Modified-Since字段(和客户端收到的Last-Modified值相等)到API端,如果校验发现资源没有发生修改,那么API端无需重新获取资源,直接返回304字段(NotModifed)给缓存,缓存给客户端返回值。如果校验发现资源发生了修改,那么API将会返回新的结果。

    我们给Api项目添加Nuget包Marvin.Cache.Headers,来实现此功能。

    首先向Program中添加服务以及引入中间件:

    Program.cs

    builder.Services.AddResponseCaching();builder.Services.AddHttpCacheHeaders(    expirationOptions =>    {        expirationOptions.MaxAge = 180;        expirationOptions.CacheLocation = CacheLocation.Private;    },    validateOptions =>    {        validateOptions.MustRevalidate = true;    });// 省略其他...app.UseResponseCaching();app.UseHttpCacheHeaders();

    同时我们需要移除之前添加的ResponseCache属性,因为新引入的库已经帮我们完成了,当然我们也可以通过以下方式覆盖全局配置:

    [HttpCacheExpiration(CacheLocation = CacheLocation.Public, MaxAge = 60)][HttpCacheValidation(MustRevalidate = false)]

    覆盖规则和框架内置的规则是一致的,我不会继续演示。

    验证3: 缓存校验

    请求仍然是获取所有的TodoLists

    响应

    我们暂时只关注响应头:

    如果在缓存失效前我们添加了一个新的TodoList,在请求头中添加If-None-Match=53154EEFAE230D733827DBDE49B42AF9再执行获取请求:

    可以看到在失效时间到期之内,Etag值已经发生了变化,校验表明资源已经改变,需要重新获取。

    如果我们再次获取相同的资源,会得到304返回:

    一点扩展

    但是如果我们仔细观察和思考就会发现,框架在实现缓存校验上存在两个问题:

    1. If-None-Match头字段是我们手动添加模拟的,这本应该由缓存中间件来完成;

    2. 在响应304的情况下,实际上是没有返回响应体的,即缓存中未修改的资源没有返回;

    这两个问题是由框架内建的ResponseCaching库导致的,可以认为它没有正确地实现缓存校验机制。为此我们有一些替代方案可供参考:

    Varnish

    Apache Traffic Server

    Squid

    当然使用专门的CDN来做缓存也是可以的。

    感谢大家的阅读,以上就是".NET 6开发中怎么实现缓存"的全部内容了,学会的朋友赶紧操作起来吧。相信小编一定会给大家带来更优质的文章。谢谢大家对网站的支持!

    缓存 资源 配置 中间件 全局 字段 相同 验证 客户 客户端 问题 属性 方式 框架 开发 内容 再次 单个 同时 数据 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 国产数据库生态风险掌控 店大侠数据库 默认密码 服务器太卡怎么找原因 网络安全有你有我简笔画 杭州康祺网络技术有限公司招聘 任子行网络安全问董秘 萧山三职计算机网络技术 网络安全领域的成就 linux服务器开发教程交流 战地1自定义服务器点不了部署 天水网络安全技能培训 网络安全保密个人自查报告 采购数据库表范式 网络安全是后端吗 电竞酒店服务器配置需求 网络安全行业如何找渠道 耕地数据库是怎么划定的 北京光学成像仿真软件开发 梦幻西游甲组服务器 腾讯贵州服务器云空间 最全的蛋白组数据库 考研网络技术考哪些 企业管理有什么软件开发 江苏计算机软件开发定制费用 紫鲸互联网科技有限公司官网 饥荒联机如何设置服务器 云免服务器对接 提高自我防范意识网络安全金句 白云区国内网络技术开发公司 苹果链接苹果服务器出问题
    0