.NET 6开发之实现缓存过程详解

2022-04-16 14:25:32
目录
需求目标原理与思路实现使用原生ResponseCaching实现缓存使用Marvin.Cache.Headers实现更多缓存功能一点扩展总结参考资料

需求

有的时候为了减少客户端请求相同资源的逻辑重复执行,我们会考虑使用一些> { 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

响应

我们暂时只关注响应头:

.NET 6开发之实现缓存过程详解

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

.NET 6开发之实现缓存过程详解

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

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

.NET 6开发之实现缓存过程详解

一点扩展

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

If-None-Match头字段是我们手动添加模拟的,这本应该由缓存中间件来完成;在响应304的情况下,实际上是没有返回响应体的,即缓存中未修改的资源没有返回;

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

Varnish

Apache Traffic Server

Squid

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

总结

在本文中我们主要演示了如何借助框架的缓存机制来实现请求资源的缓存,尽管在缓存校验的实现上,官方提供的库目前来看并没有能很好地完成功能以外,对于我们基本的使用场景来说已经够用了。下一篇文章我们来看怎么实现接口的限流。

参考资料

1.Varnish

2.Apache Traffic Server

3.Squid