当前位置: 首页 > news >正文

深入理解 Polly:.NET Core 中的健壮错误处理策略

在现代软件开发中,错误处理是构建高可用、健壮系统的关键之一。尤其是当应用依赖外部服务(如 API、数据库或其他网络资源)时,临时的服务中断、超时或其他不可预见的错误都会影响应用的稳定性。为了提升系统的容错能力,Polly 成为 .NET 开发者的重要工具。Polly 是一个功能强大的 .NET 库,提供了多种常用的错误处理策略,如重试、断路器、回退等,帮助开发者在发生错误时进行优雅的恢复和处理。

本文将深入探讨 Polly 的核心功能及其在 .NET Core 中的应用,带你一步步掌握如何通过 Polly 构建健壮的错误处理机制。

1. 什么是 Polly?

Polly 是一个为 .NET 提供的开源库,旨在帮助开发者处理常见的错误处理需求。Polly 提供了一套丰富的策略,用于解决应用在与外部服务交互时可能出现的瞬时错误。它的主要功能包括:

  • 重试(Retry)

  • 断路器(Circuit Breaker)

  • 回退(Fallback)

  • 超时(Timeout)

  • 并发限制(Bulkhead Isolation)

这些策略有助于在外部依赖出现问题时,保证系统能够优雅地恢复或避免过度依赖失败的服务。

2. Polly 核心策略

2.1 重试(Retry)

重试策略在遇到可恢复的错误时会自动重试失败的操作。比如,某个 HTTP 请求因为网络波动而失败,重试策略可以尝试再次发起请求,直到成功或达到最大重试次数。

示例代码:

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;public class Program
{public static async Task Main(string[] args){var policy = Policy.Handle<HttpRequestException>()  // 捕获 HttpRequestException 异常.RetryAsync(3);  // 重试 3 次HttpClient client = new HttpClient();await policy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();  // 请求失败会抛出异常return response;});}
}

在上面的代码中,如果 HTTP 请求因某种原因失败,Polly 会自动重试最多 3 次。

2.2 断路器(Circuit Breaker)

断路器策略用于避免持续失败的操作对系统造成更大的影响。当一个操作连续失败多次时,断路器会启动,阻止进一步的请求执行,直到外部服务恢复正常。

示例代码:

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;public class Program
{public static async Task Main(string[] args){var policy = Policy.Handle<HttpRequestException>().CircuitBreakerAsync(2, TimeSpan.FromMinutes(1));  // 2 次失败后断路,1 分钟内不再尝试HttpClient client = new HttpClient();try{await policy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();return response;});}catch (BrokenCircuitException){Console.WriteLine("Circuit is broken. Requests are not being executed.");}}
}

在这个例子中,如果 HTTP 请求连续失败两次,断路器就会打开,接下来的请求将不会再发送,直到 1 分钟后恢复正常。

2.3 回退(Fallback)

回退策略是在操作失败时提供一个备选方案。通常用于在外部服务调用失败时,返回默认数据或缓存内容,而不是直接报错。

示例代码:

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;public class Program
{public static async Task Main(string[] args){var fallbackPolicy = Policy.Handle<HttpRequestException>().FallbackAsync(Task.FromResult("Fallback response"),  // 返回回退结果onFallbackAsync: (outcome, context) =>{Console.WriteLine("Fallback triggered due to: " + outcome.Exception?.Message);return Task.CompletedTask;});HttpClient client = new HttpClient();var result = await fallbackPolicy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();return await response.Content.ReadAsStringAsync();});Console.WriteLine(result);  // 如果失败,返回回退结果}
}

当请求失败时,FallbackAsync 会提供一个替代方案(这里是一个字符串“Fallback response”),从而避免应用崩溃。

2.4 超时(Timeout)

超时策略限制了操作的最大执行时间。如果操作超时,Polly 会自动终止该操作。

示例代码:

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;public class Program
{public static async Task Main(string[] args){var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromSeconds(5));  // 设置请求最大超时时间为 5 秒HttpClient client = new HttpClient();try{var result = await timeoutPolicy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();return await response.Content.ReadAsStringAsync();});}catch (TimeoutRejectedException){Console.WriteLine("The request timed out.");}}
}

在这个例子中,TimeoutAsync 设置了最大超时限制。如果请求没有在 5 秒内完成,将抛出 TimeoutRejectedException

2.5 并行限制(Bulkhead Isolation)

并行限制策略用于限制系统能够同时处理的并发操作数量。如果超过最大并发数,后续请求将被排队或拒绝。

示例代码:

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;public class Program
{public static async Task Main(string[] args){var bulkheadPolicy = Policy.BulkheadAsync(2, 4);  // 最多 2 个并行请求,最多 4 个排队请求HttpClient client = new HttpClient();await Task.WhenAll(bulkheadPolicy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();}),bulkheadPolicy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();}));}
}

通过使用 BulkheadAsync,你可以避免系统因过多并发请求而崩溃,限制并发请求的数量,确保系统的稳定性。

3. 策略组合与复合策略

Polly 还支持将多个策略组合成一个复合策略(Policy Wrap)。这样,你可以在一个操作中依次应用多个策略,比如先尝试重试,接着使用断路器,最后返回回退结果。

示例代码:

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;public class Program
{public static async Task Main(string[] args){var policy = Policy.Handle<HttpRequestException>().RetryAsync(3).WrapAsync(Policy.Handle<HttpRequestException>().CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)));HttpClient client = new HttpClient();try{await policy.ExecuteAsync(async () =>{var response = await client.GetAsync("https://example.com");response.EnsureSuccessStatusCode();return response;});}catch (BrokenCircuitException){Console.WriteLine("The circuit is broken.");}}
}

通过 WrapAsync,你将重试策略和断路器策略结合起来,形成一个更复杂的容错处理机制。

4. 小结

Polly 为 .NET Core 应用提供了一种简洁而强大的错误处理机制。它的策略(重试、断路器、回退等)能够有效提高系统的稳定性,减少因外部服务不可用或临时故障而导致的系统崩溃。在实际开发中,合理利用 Polly 的策略,可以大大提升系统的健壮性和容错能力。

如果你还没有开始使用 Polly,不妨尝试在项目中引入它,特别是在与外部 API 或服务交互时,它能帮助你更好地处理瞬时故障,保证系统稳定运行。

相关文章:

  • LVGL(lv_btnmatrix矩阵按钮)
  • [特殊字符] 免税商品优选购物商城系统 | Java + SpringBoot + Vue | 前后端分离实战项目分享
  • Telnetlib 库完全指南
  • 常见的排序算法(Java版)简单易懂好上手!!
  • AI日报 - 2024年05月12日
  • js事件循环机制
  • 深入理解AMBA总线(六)AHB-lite Slave响应和其它控制信号
  • 关于阿里云OSS传输加速域名(全地域上传下载加速)
  • Python httpx库终极指南
  • Day116 | 灵神 | 二叉树 | 二叉搜索树中第K小的元素
  • 无人甘蔗小车履带式底盘行走系统的研究
  • 关于物联网的基础知识(二)——物联网体系结构分层
  • 网络调优的策略有哪些
  • Oracle 通过 ROWID 批量更新表
  • Spring Web MVC响应
  • 《Effective Python》第1章 Pythonic 思维详解——item03-05
  • AUTOSAR图解==>AUTOSAR_TR_HWTestManagementIntegrationGuide
  • JVM 监控
  • 闲鱼智能客服机器人-实现闲鱼平台7×24小时自动化值守
  • 甜蜜聊天话术库
  • 美凯龙:董事兼总经理车建兴被立案调查并留置
  • 上海团队在医学顶刊连发两文,率先提出“证据污染”循证概念
  • 上海浦东机场1号、2号航站楼均推出国内出发安检24小时服务
  • 农林生物安全全国重点实验室启动建设,聚焦重大有害生物防控等
  • 耿军强任陕西延安市领导,此前任陕西省公安厅机场公安局局长
  • 中山大学人类学系原系主任冯家骏逝世,享年95岁