zoukankan      html  css  js  c++  java
  • 使用 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 "超时";
    	}
    }
    
  • 相关阅读:
    request.getAttribute()和 request.getParameter()的区别
    jquery中$.get()提交和$.post()提交有区别吗?
    jQuery有几种选择器?
    jQuery 库中的 $() 是什么?
    JavaScript内置可用类型
    MySQL数据库中,常用的数据类型
    简单叙述一下MYSQL的优化
    什么是JDBC的最佳实践?
    Vue官网教程-条件渲染
    Vue官网教程-Class与Style绑定
  • 原文地址:https://www.cnblogs.com/myzony/p/11005348.html
Copyright © 2011-2022 走看看