美文网首页编程语言爱好者码农的世界.NET
Polly 故障处理(一): 重试策略

Polly 故障处理(一): 重试策略

作者: BeckJin | 来源:发表于2018-05-14 00:12 被阅读12次

在微服务架构下,我相信大家都应该遇到类似以下问题:

  1. 某些接口异常,最终造成应用程序池奔溃;
  2. 某些接口不稳定、偶尔超时,数据获取异常;
  3. 某些服务不稳定,调用方连接不上;
  4. 某些服务异常,最终主服务挂掉(雪崩效应);

当然在实际情况下,可能有时我们只需要确保提供给用户的服务是可用状态,不出现 "Service Unavailable" 这样的画面基本上也可以。至于接口偶尔异常,可能对某些类型的项目来说并不太关键,用户可能通过重新请求、刷新页面就可以解决,当然我们还可以在代码层面做兼容,满满的try/catch、for/while 循环解决重试来保证更高的可靠性。

不管这么样,任何异常情况都不是我们期望的,但它却永远存在,”投机取巧“ 终将不是谨慎的做法,随着一个项目关联的微服务越来越多,以上问题会表现得越突出,所以选择一个好的故障处理库或框架变得尤为重要。

这里介绍一个轻量的故障处理库 PollyPolly 是一个.NET弹性和瞬态故障处理库,它允许我们以非常顺畅和线程安全的方式来执行诸如重试、断路器、超时、隔离、缓存、后退等策略, 能为我们在微服务架构提供更稳定的服务。当然,目前的 Service Mesh 显得更高大上,而且更强大,它更偏向从运维层面解决以上问题。不过这些都得看项目的需要来决策。

Polly

Polly 的使用相对比较简单,当然还是得看项目结构。我们的主项目在调用微服务接口时使用了AOP,类似这种情况下,所以调用微服务的接口都是统一入口,所以我们只需要在AOP内加上 Polly 的一些策略,其他代码不用做任何修改,就可以解决一些问题了。

安装:

Install-Package Polly

使用步骤说明:

  1. 定义策略
  2. 执行方法

我们项目中的 Polly 部分代码如下:

public void Intercept(IInvocation invocation)
{
    // some code 
    try
    {
        // 创建一个策略,如果 invocation.Proceed 的执行出现 Grpc.Core.RpcException 异常,并且 StatusCode == Grpc.Core.StatusCode.Unavailable,则重试一次
        var policy = Policy
        .Handle<Grpc.Core.RpcException>(t => t.Status.StatusCode == Grpc.Core.StatusCode.Unavailable)
        .Retry(); // 默认一次

        // 将策略应用到 invocation.Proceed 方法上
        policy.Execute(invocation.Proceed);
    }
    catch (Exception ex)
    {
        // some code 
        Console.WriteLine($"{ ex.Message},{ex.StackTrace}");
    }
}

策略条件定义

策略的执行需要依赖于条件,Polly 支持对异常与结果进行策略条件定义。

异常

// 指定某个异常
Policy
  .Handle<SomeExceptionType>();

// 指定某个异常条件
Policy
  .Handle<SomeExceptionType>(ex => ex.xxx == "xxx")

// 指定多个异常
Policy
  .Handle<SomeExceptionType1>()
  .Or<SomeExceptionType2>()

// 指定多个可能异常条件
Policy
  .Handle<SomeExceptionType1>(ex => ex.xxx1 == "xxx")
  .Or<SomeExceptionType2>(ex => ex.xxx2 == "xxx")

返回结果

// 指定某个结果
Policy
  .HandleResult<ResponseMessage>(r => r.xxx == "xxx")

// 指定多个可能的结果
Policy
  .HandleResult<ResponseMessage>(r => r.xxx1 == "xxx")
  .OrResult<ResponseMessage>(r => r.xxx2 == "xxx")

重试策略(Retry )

// 指定异常下重试一次
Policy
  .Handle<SomeExceptionType>()
  .Retry();

// 指定异常下重试3次
Policy
  .Handle<SomeExceptionType>()
  .Retry(3);

// 指定异常下无限重试
Policy
  .Handle<SomeExceptionType>()
  .RetryForever();

// 每次重试之间等待指定的时间间隔
Policy
  .Handle<SomeExceptionType>()
  .WaitAndRetry(new[]
  {
    TimeSpan.FromSeconds(1),
    TimeSpan.FromSeconds(3),
    TimeSpan.FromSeconds(7)
  });

Retry 可以指定一个要执行的 Action。Action 参数:exception 当前异常信息,retryCount 当前执行第几次,context 当前执行上下文信息。

测试代码:

private static int times = 0;

public static void TestPolicy()
{
    var policy = Policy
        .Handle<Exception>()
        .Retry(3, (exception, retryCount, context) => // 出异常会执行以下代码
        {
            Console.WriteLine($"exception:{ exception.Message}, retryCount:{retryCount}, id:{context["id"]}, name:{context["name"]}");
        });

    try
    {
        // 通过 new Context 传递上下文信息
        var result = policy.Execute(Test, new Context("data", new Dictionary<string, object>() { { "id", "1" }, { "name", "beck" } }));
        Console.WriteLine($"result:{result}");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

private static string Test()
{
    // 每执行一次加1
    times++;

    // 前2次都抛异常
    if (times < 3)
    {
        throw new Exception("exception message");
    }
    return "success";
}

测试结果:


retry

参考链接:

相关文章

  • Polly 故障处理(一): 重试策略

    在微服务架构下,我相信大家都应该遇到类似以下问题: 某些接口异常,最终造成应用程序池奔溃;某些接口不稳定、偶尔超时...

  • Polly 故障处理

    Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢...

  • Polly 故障处理(二): 熔断策略

    熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时、异常等情况,可以采取一定时间内熔断该...

  • 分布式术语

    容错机制 FAILOVER:故障转移,故障出现时重试其他机器,用于读操作。重试会带来延迟。 FAILBACK: 故...

  • Polly 弹性策略指南

    从官网翻译了Polly各种策略的使用场景和建议,看着别扭的地方请海涵,信达雅是个高难度的活。 弹性策略 Polly...

  • Spring Cloud Stream消费失败后的处理策略(四)

    应用场景 之前我们已经通过《Spring Cloud Stream消费失败后的处理策略(一):自动重试》一文介绍了...

  • 分布式弹力设计之重试机制

    重试机制的使用场景 重试的前提是认为故障是暂时的,不是永久的,所以重试才有意义。 使用重试机制是必须要明确哪些错误...

  • Spring Cloud Stream消费失败后的处理策略(二)

    应用场景 上一篇《Spring Cloud Stream消费失败后的处理策略(一):自动重试》介绍了默认就会生效的...

  • 线上故障处理书目录

    线上故障处理之故障信息获取源 线上故障处理之处理流程 线上故障处理之故障后处理

  • Nginx负载均衡小知识

    Nginx 负载均衡配置Nginx 重试次数限制Nginx 超时重试 Nginx 负载均衡 负载均衡策略 roun...

网友评论

    本文标题:Polly 故障处理(一): 重试策略

    本文链接:https://www.haomeiwen.com/subject/qtgldftx.html