IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> .NET Core Polly 重试 熔断 降级 -> 正文阅读

[开发测试].NET Core Polly 重试 熔断 降级

Polly是一个弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略,其主要功能如下:
重试(Retry)
断路器(Circuit-Breaker)
超时检测(Timeout)
缓存(Cache)
降级(Fallback)

1、定义异常错误的条件

// 单个异常类型
Policy.Handle<Exception>();

// 限定条件的单个异常
Policy.Handle<Exception>(ex => ex.Message == "请求超时");

// 多个异常类型
Policy.Handle<Exception>().Or<ArgumentException>();

// 限定条件的多个异常
Policy.Handle<Exception>(ex => ex.Message == "请求超时")
    .Or<ArgumentException>(ex => ex.ParamName == "ID");

// Inner Exception 异常里面的异常类型 
Policy.HandleInner<Exception>()
    .OrInner<ArgumentException>(ex => ex.ParamName == "ID");

2、定义返回结果的条件

// 返回结果加限定条件 
Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound);

// 处理多个返回结果
Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
    .OrResult(r => r.StatusCode == HttpStatusCode.BadGateway);

// 处理元类型结果 (用.Equals)
Policy.HandleResult(HttpStatusCode.InternalServerError)
    .OrResult(HttpStatusCode.BadGateway);

3、按次数重试(Retry)

// 重试1次
Policy.Handle<Exception>().Retry();

// 重试3次
Policy.Handle<Exception>().Retry(3);

// 重试3次,加上重试时的action参数
Policy.Handle<Exception>().Retry(3, (exception, retryCount) =>
{
    // do something
});

4、不断重试(直到成功)(RetryForever)

// 不断重试,直到成功
Policy.Handle<Exception>().RetryForever();

// 不断重试,带action参数在每次重试的时候执行
Policy.Handle<Exception>().RetryForever(exception =>
{
    // do something       
});

5、等待以后按次数重试(WaitAndRetry)

// 重试3次,每次等待5s
Policy.Handle<Exception>().WaitAndRetry(
    3,
    retryAttempt => TimeSpan.FromSeconds(5),
    // 处理异常、等待时间、重试第几回
    (exception, timespan, retryCount, context) =>
    {
        // do something
    });

// 重试2次,每次等等2s
Policy.Handle<Exception>().WaitAndRetry(
    2,
    retryAttempt => TimeSpan.FromSeconds(2),
    (exception, timespan, retryCount, context) =>
    {
        Console.WriteLine($"{DateTime.Now} - 重试 {retryCount} 次 - 抛出{exception.GetType()}-{timespan.TotalMilliseconds}");
    });


// 重试3次,分别等待1、2、3秒。
Policy.Handle<Exception>().WaitAndRetry(new[]
{
    TimeSpan.FromSeconds(1),
    TimeSpan.FromSeconds(2),
    TimeSpan.FromSeconds(3)
});

6、超时检查(Timeout)

// 超时1秒
Policy.Timeout(1, TimeoutStrategy.Pessimistic, (context, timespan, task) =>
{
    Console.WriteLine("执行超时,抛出TimeoutRejectedException异常");
});

Policy.Timeout(30, onTimeout: (context, timespan, task, ex) =>
{
    // do something 
});

7、熔断(CircuitBreaker)

// 连续发生两次故障,就熔断3秒
Policy.Handle<Exception>()
    .CircuitBreaker(
        // 熔断前允许出现几次错误
        2,
        // 熔断时间
        TimeSpan.FromSeconds(5),
        // 熔断时触发 OPEN
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"{DateTime.Now} - 断路器:开启状态(熔断时触发)");
        },
        // 熔断恢复时触发 // CLOSE
        onReset: () =>
        {
            Console.WriteLine($"{DateTime.Now} - 断路器:关闭状态(熔断恢复时触发)");
        },
        // 熔断时间到了之后触发,尝试放行少量(1次)的请求,
        onHalfOpen: () =>
        {
            Console.WriteLine($"{DateTime.Now} - 断路器:半开启状态(熔断时间到了之后触发)");
        }
    );

8、回退(Fallback)

// 回退策略,降级!
Policy.Handle<Exception>().Fallback(() =>
{
    // do something
    Console.WriteLine("这是一个Fallback");
}, exception =>
{
    Console.WriteLine($"Fallback异常:{exception.GetType()}");
});

9、组合Polly

var policyWrap = Policy.Wrap(fallbackPolicy, circuitBreakerPolicy, retryPolicy, timeoutPolicy);
policyWrap.Execute(() =>
{
    // do something
});

10、完整测试

public void Test()
{
    var policy = CreatePolly();
    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine($"-------------第{i}次请求-------------");
        policy.Execute(() =>
        {
            // 从10次开始,正常请求成功
            if (i < 10)
            {
                Thread.Sleep(3000);
            }
            else
            {
                Console.WriteLine($"{DateTime.Now}:请求成功");
            }
        });
        Thread.Sleep(1000);
    }
}


public ISyncPolicy CreatePolly()
{
    // 超时1秒
    var timeoutPolicy = Policy.Timeout(1, TimeoutStrategy.Pessimistic, (context, timespan, task) =>
    {
        Console.WriteLine("执行超时,抛出TimeoutRejectedException异常");
    });

    // 重试2次
    var retryPolicy = Policy.Handle<Exception>()
        .WaitAndRetry(
            2,
            retryAttempt => TimeSpan.FromSeconds(2),
            (exception, timespan, retryCount, context) =>
            {
                Console.WriteLine($"{DateTime.Now} - 重试 {retryCount} 次 - 抛出{exception.GetType()}-{timespan.TotalMilliseconds}");
            });

    // 连续发生两次故障,就熔断3秒
    var circuitBreakerPolicy = Policy.Handle<Exception>()
        .CircuitBreaker(
            // 熔断前允许出现几次错误
            2,
            // 熔断时间
            TimeSpan.FromSeconds(5),
            // 熔断时触发 OPEN
            onBreak: (ex, breakDelay) =>
            {
                Console.WriteLine($"{DateTime.Now} - 断路器:开启状态(熔断时触发)");
            },
            // 熔断恢复时触发 // CLOSE
            onReset: () =>
            {
                Console.WriteLine($"{DateTime.Now} - 断路器:关闭状态(熔断恢复时触发)");
            },
            // 熔断时间到了之后触发,尝试放行少量(1次)的请求,
            onHalfOpen: () =>
            {
                Console.WriteLine($"{DateTime.Now} - 断路器:半开启状态(熔断时间到了之后触发)");
            }
        );

    // 回退策略,降级!
    var fallbackPolicy = Policy.Handle<Exception>()
        .Fallback(() =>
        {
            Console.WriteLine("这是一个Fallback");
        }, exception =>
        {
            Console.WriteLine($"Fallback异常:{exception.GetType()}");
        });

    // 策略从右到左依次进行调用
    // 首先判断调用是否超时,如果超时就会触发异常,发生超时故障,然后就触发重试策略;
    // 如果重试两次中只要成功一次,就直接返回调用结果
    // 如果重试两次都失败,第三次再次失败,就会发生故障
    // 重试之后是断路器策略,所以这个故障会被断路器接收,当断路器收到两次故障,就会触发熔断,也就是说断路器开启
    // 断路器开启的3秒内,任何故障或者操作,都会通过断路器到达回退策略,触发降级操作
    // 3秒后,断路器进入到半开启状态,操作可以正常执行

    return Policy.Wrap(fallbackPolicy, circuitBreakerPolicy, retryPolicy, timeoutPolicy);
}

*
*
*

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:55:28  更:2022-03-30 18:57:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:10:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码