使用 Polly 实现复杂策略(超时重试)

一、背景

第一次接触 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 "超时";
    }
}

原文地址:https://www.cnblogs.com/myzony/p/11005348.html

时间: 2024-08-29 20:25:15

使用 Polly 实现复杂策略(超时重试)的相关文章

Volley超时重试机制详解

Volley超时重试机制 基础用法 Volley为开发者提供了可配置的超时重试机制,我们在使用时只需要为我们的Request设置自定义的RetryPolicy即可. 参考设置代码如下: int DEFAULT_TIMEOUT_MS = 10000; int DEFAULT_MAX_RETRIES = 3; StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<S

dubbo超时重试和异常处理

参考: https://www.cnblogs.com/ASPNET2008/p/7292472.html https://www.tuicool.com/articles/YfA3Ub https://www.cnblogs.com/binyue/p/5380322.html https://blog.csdn.net/mj158518/article/details/51228649 本篇主要记录dubbo中关于超时的常见问题,实现原理,解决的问题以及如何在服务降级中体现作用等. 超时问题

jedis超时重试机制注意事项

最近使用redis集群进行incr操作,总是发现计数不准确,后来经过检查发现redis在执行incr超时会执行重试机制,造成计数不准确,测试代码: /** * incrf: * 将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误. 本操作的值限制在 64 位(bit)有符号数字表示之内. 这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,

SpringCloud Feign 之 超时重试次数探究

SpringCloud Feign 之 超时重试次数探究 上篇文章,我们对Feign的fallback有一个初步的体验,在这里我们回顾一下,Fallback主要是用来解决依赖的服务不可用或者调用服务失败或超时,使用默认的返回值.实际应用中, 在Fallback之前,需要对服务配置重试机制,当多次重试服务,还是服务不可用的情况下,就触发Fallback. 这里,我们对重试机制配置以及重试次数进行一次探究. Feign的超时 Feign接口调用分两层,Ribbon(负载均衡)和Hystrix(熔断器

SpringCloud Fegin超时重试源码

springCloud中最重要的就是微服务之间的调用,因为网络延迟或者调用超时会直接导致程序异常,因此超时的配置及处理就至关重要. 在开发过程中被调用的微服务打断点发现会又多次重试的情况,测试环境有的请求响应时间过长也会出现多次请求,网上查询了配置试了一下无果,决定自己看看源码.本人使用的SpringCloud版本是Camden.SR3. 微服务间调用其实走的是http请求,debug了一下默认的ReadTimeout时间为5s,ConnectTimeout时间为2s,我使用的是Fegin进行微

dobbo 服务配置详解(解决超时重试问题)

<!-- reference method -->     <dubbo:reference interface="com.xx.XxxService">         <dubbo:method name="findXxx" timeout="1000"></dubbo:method>     </dubbo:reference>          <!-- service m

python 超时重试方法

在应用中,有时候会 依赖第三方模块执行方法,比如调用某模块的上传下载,数据库查询等操作的时候,如果出现网络问题或其他问题,可能有超时重新请求的情况: 目前的解决方案有 1. 信号量,但不支持window: 2.多线程,但是 如果是大量的数据重复操作尝试,会出现线程管理混乱,开启上万个线程的问题: 3.结合采用 eventlet 和 retrying模块 (eventlet 原理尚需深入研究) 下面的方法实现:超过指定时间重新尝试某个方法 # -*- coding: utf-8 -*- impor

Polly的多种弹性策略介绍和简单使用

什么是Polly? Polly是一个.NET弹性和瞬态故障处理库.允许我们以非常顺畅和线程安全的方式来执行诸如行重试,断路,超时,故障恢复等策略. Polly项目地址:https://github.com/App-vNext/Polly Polly提供多种弹性策略:重试(Retry),断路器(Circuit-breaker),超时检测(Timeout),缓存(Cache),降级(FallBack) 重试(Retry): 前置条件:许多故障是短暂的,并且可能在短暂延迟后自我纠正 政策如何缓解:允许

nginx的重试机制以及nginx常用的超时配置说明

nginx的重试机制 现在对外服务的网站,很少只使用一个服务节点,而是部署多台服务器,上层通过一定机制保证容错和负载均衡. nginx就是常用的一种HTTP和反向代理服务器,支持容错和负载均衡. nginx的重试机制就是容错的一种. 在nginx的配置文件中,proxy_next_upstream项定义了什么情况下进行重试,官网文档中给出的说明如下:--------------------- Syntax: proxy_next_upstream error | timeout | invali