『容错机制』 .NET 弹性和瞬态故障处理库Polly应用详解

简介: 所谓瞬态故障,就是说故障不是必然会发生的,而是偶然可能会发生的,比如网络偶尔会突然出现不稳定或无法访问这种故障。至于弹性,就是指应对故障 Polly 的处理策略具有多样性和灵活性,它的各种策略可以灵活地定义和组合。

Polly官方介绍

Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.

翻译过来大概意思是:Polly 是一个 .NET 弹性和瞬态故障处理库,允许开发人员以线程安全的方式来实现重试、断路、超时、隔离和回退策略。

首先这里的说的瞬态故障包含了程序发生的异常和出现不符合开发者预期的结果。

所谓瞬态故障,就是说故障不是必然会发生的,而是偶然可能会发生的,比如网络偶尔会突然出现不稳定或无法访问这种故障。至于弹性,就是指应对故障 Polly 的处理策略具有多样性和灵活性,它的各种策略可以灵活地定义和组合。


一 、熔断降级——概念及原理

1. 什么是熔断

熔断就是在被调用端出现宕机,和超时两种情况出现的一种策略应对机制。

熔断就好比保险丝,我们先来看一看保险丝的情况
在这里插入图片描述

2. 为什么要使用熔断

​ 1、服务调用出现异常(包括超时和宕机两种情况)

​ 如果服务连续几次都出现异常,那么就将服务进行熔断一段时间,
在这里插入图片描述

3. 什么是降级

在这里插入图片描述

4. 为什么要使用降级

​ 1、服务主动降级(选择性放弃)

​ 主动将服务进行进行异常返回

​ 2、服务异常降级

​ 如果服务调用出现超时或者宕机的情况,就按照自定义的策略进行返回。

项目中熔断降级的目的是保证系统的弹性,使系统高可用
在这里插入图片描述

5. Polly熔断原理

在这里插入图片描述


二 、熔断降级——Polly介绍

1. 熔断降级工具

  1. Polly
  2. Hystrix

2. 主要功能

  • 重试(Retry)
  • 断路器(Circuit-breaker)
  • 超时检测(Timeout)
  • 缓存(Cache)
  • 降级(FallBack)

3. Polly官网地址

http://www.thepollyproject.org/

三 、熔断降级——Polly项目应用

1. Polly使用

  • 条件
  1. .Net Core项目
  2. 微服务项目
  3. Polly
  4. Polly Http扩展
  • 步骤
  1. 先通过nuget进行安装

    Microsoft.Extensions.Http.Polly

  2. 然后在HttpClient后面添加扩展方法AddPolicyHandler()
  3. 然后在团队服务里面,测试宕机,和超时情况

2. Polly策略搭配

熔断策略

.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().CircuitBreakerAsync(3, TimeSpan.FromSeconds(10), (ex, ts) => {
                Console.WriteLine($"服务{name}断路器开启,异常消息:{ex.Exception.Message}");
                Console.WriteLine($"服务{name}断路器开启时间:{ts.TotalSeconds}s");
            }, () => {
                Console.WriteLine($"服务{name}断路器重置");
            }, () => {
                Console.WriteLine($"服务{name}断路器半开启(一会开,一会关)");
            }))    

降级策略

var fallbackResponse = new HttpResponseMessage
{
    Content = new StringContent("系统出现异常,请稍后重试"),
    StatusCode = HttpStatusCode.GatewayTimeout
};

.AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(options.httpResponseMessage, async b =>
           {
               // 1、降级打印异常
               Console.WriteLine($"服务{name}开始降级,异常消息:{b.Exception.Message}");
               // 2、降级后的数据
               Console.WriteLine($"服务{name}降级内容响应:{options.httpResponseMessage.Content.ToString()}");
               await Task.CompletedTask;
           }))    

重试策略

.AddPolicyHandler(Policy<HttpResponseMessage>
              .Handle<Exception>()
              .RetryAsync(options.RetryCount)
            )

超时机制

超时机制必须要慎用,需要考虑相关服务的幂等性

.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(options.TimeoutTime)));

3. Polly封装

  • 条件
  1. IServiceCollection扩展类
  2. HttpClientPolly选项类
  • 步骤
  1. 创建PollyHttpClientServiceCollectionExtensions
/// <summary>
/// Httpclient扩展方法
/// </summary>
/// <param name="services">ioc容器</param>
/// <param name="name">HttpClient 名称(针对不同的服务进行熔断,降级)</param>
/// <param name="action">熔断降级配置</param>
/// <param name="TResult">降级处理错误的结果</param>
/// <returns></returns>
public static IServiceCollection AddHttpClientPolly(this IServiceCollection services,string name,Action<HttpClientPollyOptions> action)
{
    // 1、创建选项配置类
    HttpClientPollyOptions options = new HttpClientPollyOptions();
    action(options);
// 2、配置httpClient,熔断降级策略
services.AddHttpClient(name)
//2.1 降级策略
.AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(options.httpResponseMessage, async b =>
{
   Console.WriteLine($"服务{name}开始降级,异常消息:{b.Exception.Message}");
   Console.WriteLine($"服务{name}降级内容响应:{options.httpResponseMessage.Content.ToString()}");
   await Task.CompletedTask;
}))
// 2.2 断路器策略
.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().CircuitBreakerAsync(options.CircuitBreakerOpenFallCount, TimeSpan.FromSeconds(options.CircuitBreakerDownTime), (ex, ts) => {
    Console.WriteLine($"服务{name}断路器开启,异常消息:{ex.Exception.Message}");
    Console.WriteLine($"服务{name}断路器开启时间:{ts.TotalSeconds}s");
}, () => {
    Console.WriteLine($"服务{name}断路器关闭");
}, () => {
    Console.WriteLine($"服务{name}断路器半开启(时间控制,自动开关)");
}))
// 2.3 重试策略
.AddPolicyHandler(Policy<HttpResponseMessage>
  .Handle<Exception>()
  .RetryAsync(options.RetryCount)
)
// 2.4 超时策略
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(options.TimeoutTime)));
return services;
}    
  1. 然后创建熔断,降级,重试,超时HttpClientPollyOptions配置类
/// <summary>
/// 超时时间设置,单位为秒
/// </summary>
public int TimeoutTime { set; get; }
/// <summary>
/// 失败重试次数
/// </summary>
public int RetryCount { set; get; }

/// <summary>
/// 执行多少次异常,开启短路器(例:失败2次,开启断路器)
/// </summary>
public int CircuitBreakerOpenFallCount { set; get; }

/// <summary>
/// 断路器开启的时间(例如:设置为2秒,短路器两秒后自动由开启到关闭)
/// </summary>
public int CircuitBreakerDownTime { set; get; }

/// <summary>
/// 降级处理(将异常消息封装成为正常消息返回,然后进行响应处理,例如:系统正在繁忙,请稍后处理.....)
/// </summary>
public HttpResponseMessage httpResponseMessage { set; get; }        
  1. 封装后的代码调用
services.AddPollyHttpClient("cyf",options => {
    options.TimeoutTime = 1;
    options.RetryCount = 3;
    options.CircuitBreakerOpenFallCount = 2;
    options.CircuitBreakerDownTime = 100;
    options.httpResponseMessage = fallbackResponse;
});
相关文章
|
11天前
|
C#
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
|
2月前
|
存储 Shell Linux
快速上手基于 BaGet 的脚本自动化构建 .net 应用打包
本文介绍了如何使用脚本自动化构建 `.net` 应用的 `nuget` 包并推送到指定服务仓库。首先概述了 `BaGet`——一个开源、轻量级且高性能的 `NuGet` 服务器,支持多种存储后端及配置选项。接着详细描述了 `BaGet` 的安装、配置及使用方法,并提供了 `PowerShell` 和 `Bash` 脚本实例,用于自动化推送 `.nupkg` 文件。最后总结了 `BaGet` 的优势及其在实际部署中的便捷性。
133 10
|
11天前
|
人工智能 自然语言处理 API
适用于 .NET 稳定的官方OpenAI库
适用于 .NET 稳定的官方OpenAI库
|
14天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
27天前
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
|
1月前
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
24 1
|
11天前
|
开发框架 安全 .NET
.NET使用Moq开源模拟库简化单元测试
.NET使用Moq开源模拟库简化单元测试~
|
1月前
|
网络协议 Unix Linux
一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
一个.NET开源、快速、低延迟的异步套接字服务器和客户端库
|
1月前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
62 8
|
1月前
|
存储 开发框架 .NET
.NET 8 实现无实体库表 API 部署服务
【10月更文挑战第12天】在.NET 8中,可通过以下步骤实现无实体库表的API部署:首先安装.NET 8 SDK及开发工具,并选用轻量级Web API框架如ASP.NET Core;接着创建新项目并设计API,利用内存数据结构模拟数据存储;最后配置项目设置并进行测试与部署。此方法适用于小型项目或临时解决方案,但对于大规模应用仍需考虑持久化存储以确保数据可靠性与可扩展性。
下一篇
无影云桌面