• .NET微服务从0到1:服务容错(Polly)


    Polly.NET 平台下的一个弹性和瞬态故障处理库,它允许开发人员以流畅和线程安全的方式表达策略,如重试、熔断器、超时、舱壁隔离和回退等

    重试

    进行一次重试

    Retry() 无参数表示重试一次

    private static async Task RetryOnce()
    {
        var policy = Policy.Handle<CustomException>()
            .Retry(3);
        await policy.Execute(() => FooFunction());
    }
    

    执行结果
    在这里插入图片描述

    进行多次重试

    Retry(N)表示执行N此重试

    var policy = Policy.Handle<CustomException>()
        .Retry(3);
    await policy.Execute(() => FooFunction());
    

    执行结果
    在这里插入图片描述

    一直重试直到成功

    使用RetryForever()不断重试

    private static async Task RetryForeverUntilSuccess()
    {
        var policy = Policy.Handle<CustomException>()
            .RetryForever();
        await policy.Execute(() => FooFunction());
    }
    

    执行结果
    在这里插入图片描述

    等待指定时间后重试

    使用WaitAndRetry()WaitAndRetryAsync()在指定等待时间后重试

    private static async Task RetryAfterWait()
    {
        var policy = Policy.Handle<CustomException>()
            .WaitAndRetryAsync(new[]
            {
                TimeSpan.FromSeconds(1),
                TimeSpan.FromSeconds(2),
                TimeSpan.FromSeconds(4)
            });
        await policy.ExecuteAsync(() => FooFunction());
    }
    

    在这里插入图片描述

    等待指定时间后不断重试直到成功

    使用WaitAndRetryForever()WaitAndRetryForeverAsync()在等待指定实际后不断重试,知道成功

    private static async Task RetryForeverUntilSuccessAfterWait()
    {
        var policy = Policy.Handle<CustomException>()
            .WaitAndRetryForeverAsync(retryAttempt =>
            TimeSpan.FromSeconds(1));
        await policy.ExecuteAsync(() => FooFunction());
    }
    

    在这里插入图片描述

    每一次重试前的自定义逻辑处理

    每一次重试前,我们可以自定义一些逻辑处理,比如日志记录等。

    private static async Task RetryManyWithCustomLogic()
    {
        var policy = Policy.Handle<CustomException>()
            .Retry(3, onRetry: (exception, retryCount) =>
            {
                Console.WriteLine($"{nameof(RetryManyWithCustomLogic)},第{retryCount}重试:{exception.Message}");
            });
        await policy.Execute(() => FooFunction());
    }
    

    执行结果
    在这里插入图片描述

    熔断

    使用CircuitBreaker对调用进行熔断控制

    public static async Task CircuitBreaker()
    {
        // 熔断策略:如果连续3次出发了CustomException异常,将在2秒内终止所有请求
        var policy = Policy.Handle<CustomException>()
            .CircuitBreaker(3, TimeSpan.FromSeconds(2));
        for (int i = 0; i < 10; i++)    // 模拟10次调用
        {
            try
            {
                await policy.Execute(() => FooFunction());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                await Task.Delay(1000);
            }
        }
    }
    

    执行结果
    在这里插入图片描述

    回退(Fallback)

    Fallback可以让我们程序咋发生一些故障时,提供备份操作(应急计划)

    public static void Fallback()
    {
        var policy = Policy.Handle<CustomException>()
            .Fallback(async () => FunctionFallback());
        policy.Execute(() => Function());
    }
    

    在这里插入图片描述

    上文中的一些省略的代码

    • 定义一个异常/故障
    class CustomException : Exception
    {
        public CustomException(string message) : base(message){}
    }
    
    • 要执行的函数
    static int ctr = 0;
    static Task FooFunction()
    {
        ctr++;
        if (ctr >= 11)  // 假设重试10次执行成功
        {
            return default;
        }
        Console.WriteLine($"{DateTime.Now:HH:mm:ss fff} {nameof(FooFunction)}:第{ctr}次执行");
        throw new CustomException($"{nameof(FooFunction)}发生异常");
    }
    static void Function()
    {
        try
        {
            throw new CustomException($"{nameof(Function)}发生异常");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"执行{nameof(Function)}发生异常:{ex.Message}");
            throw;
        }
    }
    
    static void FunctionFallback()
    {
        Console.WriteLine($"执行{nameof(FunctionFallback)}");
    }
    
    • 主函数
    static async Task Main(string[] args)
    {
        Console.WriteLine("开始执行");
        try
        {
           await RetryOnce();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{nameof(Main)}发生异常:{ex.Message}");
        }
        finally
        {
            Console.WriteLine("执行结束");
        }
    }
    

    参考

    ASP VNext 开源服务容错处理库Polly使用文档

  • 相关阅读:
    SystemTap
    在qemu上运行BusyBox
    Initramfs 原理和实践
    在qemu环境中用gdb调试Linux内核
    [转载] 你所不知道的TIME_WAIT和CLOSE_WAIT
    Linux VXLAN
    :not伪类选择器一些错误的写法
    c# 微软小冰-虚拟女友聊天
    Django使用表单操作数据库
    Django内置过滤器详解附代码附效果图--附全部内置过滤器帮助文档
  • 原文地址:https://www.cnblogs.com/zhaobingwang/p/12535481.html
Copyright © 2020-2023  润新知