翻译自 :Cache · App-vNext/Polly Wiki · GitHub

点此跳转到系列

目录https://blog.csdn.net/weixin_41957094/article/details/124854458

Cache (v5.4.0 起可用)

目标

从可用的缓存中获取返回值.

前提: '想当比例的请求是类似请求'

Polly 的CachePolicy是通读缓存模式的一种实现, 这种模式也叫做 cache-aside pattern. 通过从缓存中获取结果来减少总体的调用耗时和网络流量.

从内存缓存中检索结果可以完全消除下游调用. 分布式缓存可用用于上游节点之间共享缓存; 也可以用于从相邻网络中获取资源而不是从下游获取(PS:例如CDN静态文件缓存); 也可用用于应用程序内存缓存不足的替代.

使用缓存供应器(CacheProviders)

Polly 的 CachePolicy需要搭配缓存供应器(ISyncCacheProvider或 IAsyncCacheProvider 的实现).

下方列表列取列取了一些已实现的缓存供应器,可获取对应的Nuget包使用:

Package Description Supported targets
Polly.Caching.Memory
(nuget for Polly >=6.0.1 ; nuget for Polly <=5.9.0 ; github and doco)
一种基于 .NET Framework / .NET Core 实现的本地内存缓存供应器. .NET 4.0
.NET 4.5
.NET Standard 1.1 (supports .NET Core and Xamarin)
.NET Standard 2.0
Polly.Caching.Distributed
(nuget ; github and doco)
支持基于.NET Core的所有分布式缓存 IDistributedCache, 支持Redis和SqlServer缓存供应器. .NET Standard 1.1 (supports .NET Core and Xamarin)
.NET Standard 2.0

Use the below compatibility grid to select the correct version of cache providers to use with your version of Polly:

Version of Polly Version of above cache providers to use
V6及之前版本 v2
v7 起 v3 起

使用

  • 缓存的Key取决于所使用的Key策略.
  • 对应的缓存Key中有对应的缓存值时,执行顺序:
    • 传递给.Execute(...)或类似的委托不被调用执行
    • 从缓冲中获取返回值.
  • 对应的缓存Key中没有对应的缓存值时,执行顺序:
    • 传递给.Execute(...)或类似的委托正常调用执行
    • 使用配置的生存时间策略将检索到的值放入缓存中
    • 返回检索到的值.

语法

CachePolicy 的定义

CachePolicy cache = Policy.Cache(ISyncCacheProvider cacheProvider, TimeSpan ttl | ITtlStrategy ttlStrategy[, ICacheKeyStrategy cacheKeyStrategy | Func<Context, string> cacheKeyStrategy][, Action<Context, string, Exception> onCacheError]|[, Action<Context, string> onCacheGet, Action<Context, string> onCacheMiss, Action<Context, string> onCachePut, Action<Context, string, Exception> onCacheGetError , Action<Context, string, Exception> onCachePutError]);CachePolicy cache = Policy.CacheAsync(IAsyncCacheProvider cacheProvider, TimeSpan ttl | ITtlStrategy ttlStrategy[, ICacheKeyStrategy cacheKeyStrategy | Func<Context, string> cacheKeyStrategy][, Action<Context, string, Exception> onCacheError]|[, Action<Context, string> onCacheGet, Action<Context, string> onCacheMiss, Action<Context, string> onCachePut, Action<Context, string, Exception> onCacheGetError , Action<Context, string, Exception> onCachePutError]);CachePolicy<TResult> cache = Policy.Cache<TResult>(ISyncCacheProvider<TResult> cacheProvider, /* etc */);CachePolicy<TResult> cache = Policy.CacheAsync<TResult>(IAsyncCacheProvider<TResult> cacheProvider, /* etc */);

缓存策略的使用

就像其他Polly策略一样, 一个缓存策略也可以被多处功能点代码复用. 通过将Context实例传递给委托执行的代码,可以为特定执行指定缓存键:Context实例上的OperationKey是将缓存的键。

TResult result = await cachePolicy.ExecuteAsync(context => getFoo(), new Context("FooKey"));

上面的模式假设你正在使用默认缓存键策略。

你也可以在配置策略是指定 自定义的缓存键策略 .

参数

缓存供应器

cacheProvider: 提供所需要的缓存.

Polly 的 CachePolicy需要搭配缓存供应器(ISyncCacheProvider或 IAsyncCacheProvider 的实现).: 已实现的缓存供应器可以参考上表,或者你自定义缓存供应器

序列化器(见下面)也可以与缓存提供程序一起使用,将执行的“TResult”类型序列化为供应器所需的“TCache”类型。

相同的缓存供应器和序列化器实例也可以在多处复用。

ttl

TimeSpan ttl: 缓存项的生存时间(Time-to-live, ttl),即从条目放入缓存的那一刻起的相对的、非滑动的持续时间。

例如,如果传入' TimeSpan.FromMinutes(5) ', ' cacheProvider '应该认为该条目在5分钟内有效。

ttl策略 (上述TTL的替代方案)

ITtlStrategy ttlStrategy: 除了上面简单的“TimeSpan ttl”,它还提供了一些ttl策略。

RelativeTtl

RelativeTtl(TimeSpan ttl): 等价于上面的 ttl .

AbsoluteTtl

AbsoluteTtl(DateTimeOffset absoluteExpirationTime): 指示cacheProvider应使缓存项在给定的绝对时间过期。

SlidingTtl

SlidingTtl(TimeSpan slidingTtl): 指示cacheProvider应将缓存项视为具有指定时间跨度的滑动生存时间。 例如,如果传入TimeSpan.FromMinutes(5), 即每次缓存项被命中时cacheProvider应该在接下来的五分钟认为该缓存项仍然有效。

ContextualTtl

ContextualTtl: 表名执行应该从传递给执行的Context 参数中的context[ContextualTtl.TimeSpanKey]获取ttl 。

这允许你定义一个中央缓存策略,通过将期望的ttl放在Polly的执行上下文中,在不同的调用地点使用不同的ttl。例如:

context[ContextualTtl.TimeSpanKey] = TimeSpan.FromMinutes(5);
context[ContextualTtl.SlidingExpirationKey] = true; // if desired; if not set, false is assumed

ResultTtl

ResultTtl: 指定一个函数,该函数将用于根据缓存的ResultTtl项计算ttl 。这在任何需要结果表明(可能通过头)应该缓存多长时间的场景中都是有用的。 例如,调用获得授权令牌,调用结果还告诉您该令牌的有效时间。

ResultTtl(Func<TResult, Ttl>): 指定一个基于缓存的“TResult”项计算Ttl的函数.

ResultTtl(Func<Context, TResult, Ttl>): 指定一个函数,根据缓存的“TResult”项和执行的“Context”计算缓存的生存时间。

默认缓存键策略

如果不指定 cacheKeyStrategy, 缓存的键就是用代码执行Context的 OperationKey(context.OperationKey). 例如:

TResult result = await cache.ExecuteAsync(async context => await getFooAsync(), new Context("FooKey")); // "FooKey" is the cache key to use in this execution.

如果context.OperationKey不指定 (不给执行传入Context , 或者不设置context.OperationKey), 则不缓存结果值, 传递给.Execute(...) (或类似) 的委托调用正常执行.

v6及之前的版本, OperationKey 被命名为ExecutionKey.

自定义缓存键策略

Func<Context, string> cacheKeyStrategy:允许使用自定义策略,该策略在执行中使用更加具体的缓存键。 例如,将执行中的guid与缓存Key结合起来: // configuration CachePolicy cache = Policy.CacheAsync(cacheProvider, TimeSpan.FromMinutes(5), context => context.OperationKey + context["guid"]);

 // usage, elsewhereGuid guid = ... // from somewhereContext policyExecutionContext = new Context("GetResource-");policyExecutionContext["guid"] = guid.ToString();TResult result = await cache.ExecuteAsync(async context => await getResourceAsync(guid), policyExecutionContext); // "Resource-SomeGuid" is the key used in this execution, if guid == SomeGuid.

ICacheKeyStrategy cacheKeyStrategy: 在一些重载中作为参数,用于更复杂的函数。

使用序列化器

一些缓存提供商(如Redis)以特定类型存储缓存项(如string 或byte[]),要求你序列化更复杂的类型到那些(string or byte[])。

以下已存在的序列化器可用于Polly策略:

Package Description
Polly.Caching.Serialization.Json
(nuget ; github and doco)
一个基于Newtonsoft.Json实现的可序列化任何类型为String的序列化器(NuGet Gallery | Newtonsoft.Json 13.0.1).

Polly 缓存策略的序列化器的使用注意事项请参阅这里 . 实现新的序列化器也很容易(实现缓存序列化器).

与策略操作交互

onCacheGet

可选的onCacheGet委托允许在从缓存中检索值时执行特定的代码(例如日志记录)。

onCacheMiss

一个可选的onCacheMiss委托允许特定的代码执行(例如日志),当无法命中缓存时执行(一个值在缓存中找不到给定的Key)。

onCachePut

可选的onCachePut委托允许在值被放入缓存后执行特定的代码(例如日志记录)。

onCacheError

如果对底层的cacheProvider的任何调用引发异常,可选的onCacheError委托允许执行特定的代码(例如日志记录)。 如果配置了onCacheError委托,它将同时用于onCacheGetErroronCachePutError

onCacheGetError

另一个可选的onCacheGetError委托是onCacheError的更特定版本,只有在调用底层的cacheProviderget缓存抛出异常时才会执行。

onCachePutError

另一个可选的onCachePutError委托是onCacheError的更具体版本,只有当对底层的cacheProvider的put调用抛出异常时才会执行。

所有以上委托的输入参数

以上所有委托都接受执行的“Context”和缓存键“string”作为输入参数。 错误捕获委托也接受由缓存提供程序抛出的“Exception”。

抛出异常

不会因为缓存操作而引起系统异常。 如果底层的cacheProvider在缓存操作期间抛出异常:

  • 如果配置了捕获缓存的委托,则异常会传递给相关的onCacheErroronCacheGetError 或onCachePutError委托。
  • 继续执行. 例如,如果底层的' cacheProvider '在检查缓存是否包含给定键的值时抛出,则执行将其视为cache miss,并调用传递给' . execute(…)'的委托。
    • 也就是说, 在将异常传递给onCacheErroronCacheGetError 或onCachePutError用于(比如)日志记录之后,执行有意地吞下该异常。这样,缓存本身就永远不会使应用程序宕机。

推荐用法

在“PolicyWrap”内放置缓存策略

参见策略组合使用指导. :CachePolicy通常应该放在PolicyWrap的最外面,放在FallbackPolicy的外面。

没返回值的执行

如果缓存策略所执行的业务代码没有返回值, 缓存操作自然就跳过 而不会抛出异常 (因为本身就没有结果可缓存). 这允许CachePolicy包含在PolicyWrap中,PolicyWrap有时用于返回treresult 的执行,有时用于返回void,而不会抛出异常。

只选择性地缓存响应

在某些情况下,您可能只想缓存执行的某些响应,而不是其他响应。 一个典型的例子是当CachePolicy管理的代码返回'HttpResponseMessage'时,你只想在HttpResponseMessage StatusCode = = HttpStatusCode.OK 时进行缓存。

这可以通过使用 ResultTtl策略来实现,该策略通过返回值中的'Ttl'来判断是否需要缓存。TimeSpan.Zero标识不需要缓存:

Func<Context, HttpResponseMessage, Ttl> cacheOnly200OKfilter =(context, result) => new Ttl(timeSpan: result.StatusCode == HttpStatusCode.OK ? TimeSpan.FromMinutes(5) : TimeSpan.Zero, slidingExpiration: true);IAsyncPolicy<HttpResponseMessage> cacheOnly200OKpolicy = Policy.CacheAsync<HttpResponseMessage>(cacheProvider: /* the cache provider you are using */,ttlStrategy: new ResultTtl(cacheOnly200OKfilter),onCacheError: /* whatever cache error logging */); // (or other richer CacheAsync overload taking an ITtlStrategy ttlStrategy)

ITtlStrategy 返回TimeSpan.Zero, 策略跳过将返回值放到缓存中这一步骤.

_注意 在根据HttpResponseMessage的级别缓存时需要注意一些问题: 参见讨论: Is caching at the HttpResponseMessage level the right fit?.

为值类型缓存' default(TResult) '

在Polly v6版本, 缓存策略不缓存“default(TResult)”的结果值, 类似于.NET框架的原始约定,缓存返回null意味着在缓存中找不到该键的值. 一个不不好的影响是,这会阻止缓存值类型的default(TResult)(对于default(TResult) != null) 。在 Polly的 v6版本, 为了确保您可以为值类型缓存default(TResult),请将执行类型更改为TResult?

从Polly v7.0.0(使用缓存提供程序>=v3.0.0)开始,缓存策略允许对所有值和引用类型缓存“null”和“default(TResult)”。

线程安全和策略复用

线程安全

CachePolicy的内部操作是线程安全的:一个实例上的多个调用时线程安全的 (假设配置的cacheProvider实现也是线程安全的).

策略复用

CachePolicy 实例可以在多个调用点复用.

cacheProvider 实例可以在多个`CachePolicy和调用点上重用。

序列化器实例可以跨多个' CachePolicy '和调用点重用。

在重用策略时,使用不同的' OperationKey '来指定缓存键(如果使用了' DefaultCacheKeyStrategy '),并在日志和度量中区分不同的调用站点用法。

实现缓存提供程序和序列化程序

缓存提供程序

参见 实现新的缓存提供程序

创建和使用序列化器

参见 Cache · App-vNext/Polly Wiki · GitHub

翻译自 :Cache · App-vNext/Polly Wiki · GitHub

点此跳转到系列

目录https://blog.csdn.net/weixin_41957094/article/details/124854458

11:Polly-缓存(Cache)相关推荐

  1. 计算机缓存Cache机制理解

    1.计算机存储体系简介 存储器是分层次的,离CPU越近的存储器,速度越快,每字节的成本越高,同时容量也因此越小.寄存器速度最快,离CPU最近,成本最高,所以个数容量有限,其次是高速缓存(缓存也是分级, ...

  2. 计算机缓存Cache以及Cache Line详解

    转载: 计算机缓存Cache以及Cache Line详解 - 围城的文章 - 知乎 https://zhuanlan.zhihu.com/p/37749443 L1,L2,L3 Cache究竟在哪里? ...

  3. Java 中常用缓存Cache机制的实现

    /* *所谓缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. *内存缓存,也就是实现一个类中静态Map,对 ...

  4. php smarty安装,php smarty 安装 、配置、使用 及缓存cache的配置使用

    cache 使用: cache配置: $smarty->cache_dir = "/caches/";  //缓存目录 $smarty->caching = true; ...

  5. 转载:缓存 Cache

    /// <summary>         /// 缓存函数         /// </summary>         /// <param name="p ...

  6. java cacheutil_Java 常用缓存Cache机制的实现

    所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. 缓存主要可分为二大类:一.通过文件缓存,顾名思义文件 ...

  7. tp5缓存在html怎么用,tp5.1缓存Cache的使用

    前言:一般分类基本不会动,所以我们在分类当中加入缓存 1.控制器use use think\facade\Cache; 2.存取缓存 public function index() { if (Cac ...

  8. asp.net 应用数据缓存 -- Cache对象使用

    ASP.NET 应用数据缓存 -- Cache对象使用 [原文:http://msdn.microsoft.com/zh-cn/library/18c1wd61%28v=vs.100%29.aspx] ...

  9. ASP.NET状缓存Cache的应用-提高数据库读取速度

    ASP.NET状缓存Cache的应用-提高数据库读取速度 原文:ASP.NET状缓存Cache的应用-提高数据库读取速度 一. Cache概述        既然缓存中的数据其实是来自数据库的,那么缓 ...

  10. ASP.NET 缓存 Cache

    ASP.NET 提供一个功能完整的缓存引擎,页面可使用该引擎通过 HTTP 请求存储和检索任意对象. 缓存的生存期与应用程序的生存期相同,也就是说,当应用程序重新启动时,将重新创建缓存. 将数据添加到 ...

最新文章

  1. 代码重构中的几个概念
  2. 皮一皮:我好像知道了什么...
  3. torch 判断gpu可用
  4. 求最大整数及其最小下标
  5. UVALive - 8512——线段树维护线性基
  6. Python中的defaultdict方法
  7. 云图说 | 3分钟创建一个游戏类工作负载
  8. Windows文本文件编码
  9. 公众号openid实时存储mysql_微信--高效解决token及授权用户openid的持久化处理办法...
  10. Logistic逻辑回归用初等数学解读逻辑回归
  11. Vuex初级入门及简单案例
  12. Centos7 / RHEL 7 双网卡绑定
  13. Tip:部署sharepoint2013SP1指定SQL数据库时的小细节
  14. hdu 5053 水
  15. LDR6020 双USB-Type-C适配器方案 适用于苹果手机(仅需一颗芯片 完成PD快充)
  16. 拒绝年费自己组建MarkdownNice转微信公众号格式神器
  17. 全班抽签java程序
  18. 推荐两个免费绘图工具
  19. 刚入职!就遇到上亿(MySQL)大表的优化
  20. vb获取html中的inout,input conversion error-SWAT模型-Fortran语法讨论-专业Fortran论坛 -

热门文章

  1. linux设置设备MAC
  2. 中策大数据:在建工程是指什么?在建工程项目包含哪些类型?
  3. css文字下划线效果
  4. 导包View.OnClickListener和DialogInterface.OnClickListener冲突的解决方案
  5. 红米note9pro和红米note8pro哪个好
  6. XGBoost防止过拟合的方法
  7. Spring AOP MethodInvocation拦截器调用原理
  8. NPOI 生成word文档
  9. 物理气相沉积半导体设备 PVD DSP/ARM+FPGA控制器设计
  10. 树莓派如何查看CPU和内存占用率