首页 程序笔记 Polly重试回退熔断策略组合示例

Polly重试回退熔断策略组合示例

Polly重试回退熔断策略组合示例

假设服务A是一个集群(2个节点),首先调用其中一个节点的服务,如果失败或者超时,则用轮询的方式进行重试调用。

重试多次仍然失败,则直接返回一个替代数据(服务降级),之后一段时间,服务被熔断。再熔断时间内,所有对该服务的调用都以替代数据返回。

熔断时间过后,尝试再次调用,如果成功,则关闭熔断器,服务通道打通。否则,继续熔断这个服务一段时间。

要用到几个策略?超时策略,重试策略,断路器策略,回退策略(降级),策略组合。

实现代码如下

namespace ConsulTest
{
    public class PolicyBuilder
    {
        public static ISyncPolicy CreatePolly() {
            // 超时1秒
            var timeoutPolicy = Policy.Timeout(1, (context, timespan, task) => {
                Console.WriteLine("执行超时,抛出TimeoutRejectedException异常");
            });
            // 重试2次
            var retryProlicy = Policy.Handle<Exception>().WaitAndRetry(2,
                retryAttempt => TimeSpan.FromSeconds(2),
                (exception, timespan, retryCount, context) => {
                    Console.WriteLine($"{DateTime.Now} = 重试 {retryCount} 次 - 抛出{exception.GetType()}");
                });
            // 连续发生两次故障,就熔断3秒
            var circuitBreakerPolicy = Policy.Handle<Exception>().CircuitBreaker(
                // 熔断前允许出现几次错误
                2,
                // 熔断时间
                TimeSpan.FromSeconds(3),
                // 熔断时触发
                onBreak: (ex, breakDelay) =>
                {
                    Console.WriteLine($"{DateTime.Now} - 断路器:开启状态(熔断时触发)");
                },
                // 熔断回恢复时触发
                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()}");
            });
            // 策略从右到左依次进行调用
            return Policy.Wrap(fallbackPolicy, circuitBreakerPolicy, retryProlicy, timeoutPolicy);
        }
    }
}

测试代码如下,服务注册和服务发现代码可以参考

.NET Core Consul服务注册

.NET Core Consul服务发现

Polly瞬态故障处理熔断降级用法

namespace ConsulTest
{
    public class ConsulBasic
    {
        public static void Run() {
            var serviceProvider = new ConsulServiceProvider(new Uri("http://192.168.31.175:8500"));
            var aspNetCoreService = serviceProvider.CreateServiceBuilder(builder => {
                builder.ServiceName = "AspNetCore";
                builder.LoadBalancer = TypeLoadBalancer.RoundRobinLoad;//可选RandomLoad
                builder.UriScheme = Uri.UriSchemeHttp;
            });
            var httpClient = new HttpClient();
            var policy = PolicyBuilder.CreatePolly();
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine($"----------第{i}次请求-----------");
                policy.Execute(() => {
                    try
                    {
                        var uri = aspNetCoreService.BuildAsync("/Health").Result;
                        Console.WriteLine($"{DateTime.Now} - 正在调用:{uri}");
                        var content = httpClient.GetStringAsync(uri).Result;
                        Console.WriteLine($"返回结果:{content}");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("调用异常:"+ex.GetType());
                        // 如果你要在策略里捕捉异常,如果这个异常还是你定义的故障,一定要把这个异常抛出来
                        throw ex;
                    }
                });
                Task.Delay(500).Wait();
            }
            Console.ReadLine();
        }
    }
}

我关闭两个服务,并且运行程序,结果如下

可以看到

首先判断调用是否超时,如果超时就会触发异常,发生超时故障,然后就触发重试策略

如果重试两次中只要成功一次,就直接返回调用结果

如果重试两次都失败,第三次再次失败,就会发生故障

重试之后是断路器策略,所以这个故障会被断路器接收,当断路器收到两次故障,就会触发熔断,也就是说断路器开启

断路器开启的3秒内,任何故障或者操作,都会通过断路器到达回退策略,触发降级操作

3秒后,断路器进入到半开启状态,操作可以正常执行

接下来我开启一个服务,运行结果如下

在断路器半开启状态时,调用服务成功了,于是断路器被关闭了。

1

站心网

Polly重试回退熔断策略组合示例假设服务A是一个集群(2个节点),首先调用其中一个节点的服务,如果失败或..

为您推荐

代码照进现实:对公司管理策略的技术性解构

上学的时候觉得计算机专业的一些理论晦涩难懂,跟现实世界的关联太少,每当遇到一些精妙的设计时都会发出一种感叹:究竟是什么脑袋才能想出这么有意思的东西。一晃工作十年,阅历渐丰,隐约发现其实社会中的一些现象..

编写优秀 CSS 代码的 8 个策略

编写基本的CSS和HTML是我们作为Web开发人员学习的首要事情之一。然而,我遇到的很多应用程序显然没有人花时间真正考虑前端开发的长久性和可维护性。我认为这主要是因为许多开发人员对组织CSS / HTML和JavaScript的策..

如何更有策略的选择工作,让自己少奋斗10年?

你好,我是粥左罗,今天我们聊的话题是,职场中的一个个选择,是如何影响你的整个职业生涯的。职场上工作两三年以上的朋友可能都有过这样的感受:感觉 XXX 也没有比我强很多啊,为什么他能赚这么多?其实这不是主观..

C#中的线程安全的集合ConcurrentQueue使用示例

在多线程编程中,如何安全地在不同线程之间共享数据是一个非常重要的问题。C# 为我们提供了一些专门设计的线程安全集合,其中之一就是 ConcurrentQueue<T>。它是一种先进先出(FIFO)的数据结构,专门为多线程环境设..

CSS砌体布局示例和使用场景

CSS砌体布局(Masonry Layout)CSS砌体布局是一种网页布局技术,它的灵感来源于砖石墙的排列方式,类似于“拼图”或“拼砖”的效果。在砌体布局中,元素的排列并不完全遵循传统的网格布局规则,..

SQL语句中的EXISTS用法示例

EXISTS 是 SQL 中用于判断子查询是否返回结果的关键字。它通常用于 WHERE 子句中,结合子查询一起使用。如果子查询返回至少一行数据,EXISTS 会返回 TRUE,否则返回 FALSE。EXISTS 用法示例假设有两个表:employees..

小米开源智能家居平台 ha_xiaomi_home 使用示例

小米近期在 GitHub 上开源了名为“ha_xiaomi_home”的项目,即 Home Assistant 米家集成组件。该组件由小米官方支持,旨在让用户在 Home Assistant 中集成和控制小米 IoT 智能设备。主要特点:官方支持:..

ASP.NET MVC最常用的设计模式代码示例

ASP.NET MVC 是一个基于分层架构的框架,其核心架构本身已经实现了 MVC 模式(Model-View-Controller)。除了 MVC 模式,开发者在使用 ASP.NET MVC 开发应用时,通常会结合其他设计模式以提高代码的可维护性、可扩展..

微软官方Microsoft.Extensions.AI库使用示例

Microsoft.Extensions.AI 库介绍Microsoft.Extensions.AI 是一个扩展库,用于在 .NET 应用程序中轻松集成人工智能(AI)服务,例如 OpenAI、Azure OpenAI 和其他支持文本生成或语言模型的 API。通过与 Microsoft.Ext..

.NET C# EntityFramework(EF)连接SQLite代码示例

在.NET C#中使用Entity Framework(EF)连接SQLite数据库是一种常见的做法,可以有效地管理和操作数据。以下是一个简单的示例代码,展示了如何使用EF Core连接到SQLite数据库并执行基本的CRUD操作。首先,确保你已经..

.NET 使用HttpClientFactory+Polly替代直接使用HttpClient

在 .NET 开发中,了解如何发出高效、可靠且可伸缩的 Web 请求至关重要。曾几何时,在 .NET 的土地上,开发人员习惯于发出 Web 请求。这很简单:var client = new HttpClient();var response = await client.GetAsync..

DockerUI 中文可视化Docker管理工具使用示例

DockerUI 是由国内开发者打造的一款优秀的 Docker 可视化管理工具。该工具拥有简洁直观的UI界面,可以轻松进行Docker主机管理、集群管理,以及Docker任务的编排等操作。DockerUI不仅展示了资源利用率、系统信息和更..

高效且灵活的C++库Vince's CSV Parser用法示例

在当今的软件开发中,数据的处理和分析占据了核心地位。而CSV(逗号分隔值)文件格式因其简洁性和广泛的兼容性,成为数据交换的常用格式。然而,处理CSV文件并非易事,尤其是当文件规模庞大或格式复杂时。为了解决这..

C#发送邮件代码简洁示例(附源码下载)

C#发送邮件,主要使用的是System.Net.Mail命名空间下的方法实现,方法很简单,短短十几行代码即可完成发送,具体代码如下。 try { MailMessage myMail = new MailMessage(); myMail.From = new MailAddress..

使用htmlagilitypack+xpath抓取网页内容示例

本文使用htmlagilitypack+xpath抓取网页内容示例,用简单的例子展示如何使用htmlagilitypack抓取网页,可以用来做数据采集等功能。用htmlagilitypack+xpath抓取网页内容示例源码下载首先在nuget中获取htmlagilitypac..

EasyNetQ使用方法示例附源码

使用Nuget安装EasyNetQ本示例源码下载http://www.leavescn.com/Files/downloads/MQTest.zip创建连接:使用EasyNetQ连接RabbitMQ,是在应用程序启动时创建一个IBus对象,并且,在应用程序关闭时释放该对象。RabbitMQ..

.NET Core 日志配置,NLog配置示例

.NET Core内置的日志组件附带了以堆日志提供程序,输出到控制台,输出,系统事件。在Program.cs组件配置里可以配置,如下。Console和Debug是默认配置。publicstaticIHostBuilderCreateHostBuilder(string[]args)=>Ho..

MiniAPI参数绑定 服务注入 响应输出使用示例

在VS2022中可以使用MiniAPI。 使用MiniAPI以创建具有最小依赖项的 HTTP API。 它们非常适合于需要在 ASP.NET Core 中仅包括最少文件、功能和依赖项的微服务和应用。MiniAPI创建方法启动 Visual Studio 2022 并选择“..

.NET JWT使用方法示例

JSON Web Token(JWT)是一种用于在网络间传递声明的开放标准(RFC 7519),常用于对身份验证和授权信息进行安全传递。在.NET中,你可以使用一些库来轻松地创建和验证JWT。以下是一个简单的示例,演示如何在.NET中使..

使用.NET SDK Betalgo调用OpenAI ChatGPT API 代码示例

首先准备工作是需要有OpenAI的帐号然后获取ApiKey。目前国内IP无法注册和登陆OpenAI。翻墙后注册需要手机验证,可以通过手机验证码平台注册,注册过程非常快,花费大概1元左右。注册方法请看:最新OpenAI ChatGPT注..

发表回复

返回顶部