使用 Polly 实现复杂策略(超时重试)
2023-04-18 14:07:57 时间
一、背景
第一次接触 Polly 还是在做某个微服务系统的时候,那时只会使用单一的超时策略与重试策略,更加高级的特性就没有再进行学习了。最近开为某个客户开发 PC 端的上位机的时候,客户有个需求,在发起请求之后如果 5 秒钟没有响应则进行重试,总共可以重试 3 次,如果 3 次请求都未返回数据,就视为请求失败。
关于 Polly 的高级用法可以参考官方的 Wiki 文档即可,国内也有很多优秀的介绍文章,例如 这篇 和 这篇。
二、思路
查阅了 Polly 的官方文档之后,发现 Polly 提供了策略组合功能,每个 Policy 实例都可以调用其 Wrap()
方法与另外一个策略进行组合。
或者是通过 Policy
静态类提供的 Warp()
静态方法来指定需要组合的两个策略。
根据需求描述来看,我们需要用到超时策略和重试策略,只要将其组合即可。不过这里需要注意一个坑,即他们的组合顺序。
正确的组合顺序应该是 **重试策略.Warp(超时策略) **,而不是 超时策略.Warp(重试策略) 。这是因为在超时之后 Polly 会抛出 TimeoutRejectedException
异常,在重试策略捕获到该异常之后,就会开始重试操作,即后面组合策略的 ExecuteAsync()
方法接收的委托。
三、实现
首先我们定义一个方法,该方法用于组合策略(超时+重试),因为我这里是传入的异步委托操作,所以返回的是 AsyncPolicy
对象。
private AsyncPolicyWrap BuildTimeoutRetryPolicy(string msg)
{
// 超时策略,执行目标委托超过 5 秒则视为超时,抛出异常。
var timeoutPolicy = Policy.TimeoutAsync(5);
// 重试策略,重试 2 次,每次打印信息。
var retryPolicy = Policy.Handle<TimeoutRejectedException>().RetryAsync(2, (exception, i) =>
{
Console.WriteLine("开始第 i 次重试...");
});
return retryPolicy.WrapAsync(timeoutPolicy);
}
定义好策略之后,就是我们的实际应用了。这里说明一下执行逻辑,当第一次请求的时候如果发生了超时的情况,则进入重试策略,重试两次,当最后一次仍然抛出 TimeoutRejectedException
异常,则重试策略不再捕获,直接将异常抛出给调用者。
private async Task<string> GetResult(AsyncPolicyWrap policy)
{
try
{
return await policy.ExecuteAsync(() => SendDataAsync(sendProtocol));
}
catch (TimeoutRejectedException)
{
return "超时";
}
}
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击