From 9a978d74536ce0be967d5ea83e8244bd094b8609 Mon Sep 17 00:00:00 2001 From: bicijinlian Date: Mon, 12 Aug 2024 03:56:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/1.3.0.基础使用.管理客户端.ipynb | 123 +++++++++++++----- .../Controllers/Polly8Controller.cs | 10 ++ 2 files changed, 100 insertions(+), 33 deletions(-) diff --git a/Docs/1.3.0.基础使用.管理客户端.ipynb b/Docs/1.3.0.基础使用.管理客户端.ipynb index 10eaee0..61fee7e 100644 --- a/Docs/1.3.0.基础使用.管理客户端.ipynb +++ b/Docs/1.3.0.基础使用.管理客户端.ipynb @@ -75,10 +75,8 @@ "\n", "global using Microsoft.Extensions.DependencyInjection;\n", "global using Microsoft.Extensions.DependencyInjection.Extensions;\n", - "\n", "global using Microsoft.Extensions.Logging;\n", "global using Microsoft.Extensions.Logging.Console;\n", - "\n", "global using Microsoft.Extensions.Http.Logging;\n", "\n", "\n", @@ -1748,6 +1746,18 @@ "## 7 工厂 + Polly V8" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "IFactoryHttpClient 与 Polly配合,可轻松实现重试、熔断、降级、限流等功能,本文只是简略的给出常用的使用方法,详情会写在 Polly学习项目中。[Polly 官方参考](https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory)\n", + "使用步骤:\n", + "1. 引用 Polly v8 和 Microsoft.Extensions.Http.Polly 包\n", + "2. 配置命名客户端\n", + "3. 使用 AddTransientHttpErrorPolicy 快捷方法,配置策略\n", + "4. 使用其它方式配置,并且可以使用多策略、注册策略、上下文等功能" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1759,10 +1769,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "工厂可以和Polly(v8)一起使用:\n", - "1. 引用 Polly v8 和 Microsoft.Extensions.Http.Polly 包\n", - "2. 配置命名客户端\n", - "3. 使用 AddTransientHttpErrorPolicy 配置策略" + "使用快捷方法AddTransientHttpErrorPolicy,进行常用功能使用。" ] }, { @@ -1781,31 +1788,33 @@ }, "outputs": [], "source": [ - "//便捷应用:AddTransientHttpErrorPolicy() 方法,添加常用瞬时错误重试策略\n", + "/*\n", + " 便捷应用:AddTransientHttpErrorPolicy() 方法,添加常用瞬时错误重试策略\n", + "*/\n", "{\n", " var services = new ServiceCollection();\n", "\n", - " services.AddHttpClient(\"ClientA\")\n", + " services.AddHttpClient(string.Empty)\n", + " //配置默认命名客户端\n", " .ConfigureHttpClient(client => \n", " {\n", " client.BaseAddress = new Uri(webApiBaseUrl);\n", " })\n", + " //设置Policy错误处理快捷扩展方法\n", " .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync\n", " (\n", " new[]\n", " {\n", " TimeSpan.FromSeconds(1),\n", " TimeSpan.FromSeconds(2),\n", - " TimeSpan.FromSeconds(4)\n", + " TimeSpan.FromSeconds(4),\n", " }\n", " ))\n", - " .AddTransientHttpErrorPolicy(builder => builder.Fallback());\n", + " //可以多次调用:设置多个策略\n", + " .AddTransientHttpErrorPolicy(builder => builder.RetryAsync(1));\n", " \n", " var factory = services.BuildServiceProvider().GetService();\n", - " var clientA = factory.CreateClient(\"ClientA\");\n", - " var response = await clientA.GetAsync(\"/api/polly8/RandomException\");\n", - " response.EnsureSuccessStatusCode();\n", - " var content = await response.Content.ReadAsStringAsync();\n", + " var content = await factory.CreateClient().GetStringAsync(\"/api/polly8/RandomException\");\n", "\n", " Console.WriteLine($\"响应内容:{content}\");\n", "}" @@ -1818,6 +1827,13 @@ "### 使用通过传统 Polly 语法配置的任何策略" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "使用 AddPolicyHandler 方法及其重载也可用于接受任何 IAsyncPolicy ,因此可以定义和应用任何类型的策略:可以指定要处理的内容和处理方式。" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1834,21 +1850,53 @@ }, "outputs": [], "source": [ + "/*\n", + " 传统方式配置Polly策略\n", + "*/\n", + "//创建策略\n", "{\n", + " var services = new ServiceCollection();\n", "\n", - " var policy = Policy.Handle()\n", - " .WaitAndRetryAsync\n", - " (\n", - " new[]\n", - " {\n", - " TimeSpan.FromSeconds(1),\n", - " TimeSpan.FromSeconds(2),\n", - " TimeSpan.FromSeconds(4)\n", - " }\n", - " );\n", + " //重试策略\n", + " var retryePolicy = Policy\n", + " .Handle()\n", + " .OrResult(response => \n", + " {\n", + " return response.StatusCode == System.Net.HttpStatusCode.Created;\n", + " })\n", + " .WaitAndRetryAsync(new TimeSpan[]{TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(2)});\n", + " //调用\n", + " services\n", + " .AddHttpClient(string.Empty)\n", + " .AddPolicyHandler(retryePolicy);\n", + "\n", + " //超时策略\n", + " var timeoutPolicy = Policy.TimeoutAsync(10);\n", + " services\n", + " .AddHttpClient(\"timeoutPolicy\")\n", + " .AddPolicyHandler(timeoutPolicy);\n", + " \n", + " /* 普通策略转换\n", + " 所有通过 HttpClient 的调用都返回 HttpResponseMessage 因此配置的策略必须是 IAsyncPolicy \n", + " 通过简单、便捷的 AsAsyncPolicy()方法,将非通用策略 IAsyncPolicy 转换为 IAsyncPolicy \n", + " */\n", + " var timeoutPolicy2 = Policy.TimeoutAsync(2);\n", + "\n", + " services\n", + " .AddHttpClient(\"timeoutPolicy2\")\n", + " //转换通用策略\n", + " .AddPolicyHandler(timeoutPolicy2.AsAsyncPolicy());\n", + "}\n", + "\n", + "//示例\n", + "{\n", + " //创建策略\n", + " var policy = Policy.RateLimitAsync(3,TimeSpan.FromSeconds(10));\n", + "\n", + " //使用\n", " var services = new ServiceCollection();\n", "\n", - " services.AddHttpClient(\"ClientA\")\n", + " services.AddHttpClient(string.Empty)\n", " .ConfigureHttpClient(client => \n", " {\n", " client.BaseAddress = new Uri(webApiBaseUrl);\n", @@ -1866,14 +1914,16 @@ " )\n", " )\n", " .AddPolicyHandler(policy);\n", - " \n", - " var factory = services.BuildServiceProvider().GetService();\n", - " var clientA = factory.CreateClient(\"ClientA\");\n", - " var response = await clientA.GetAsync(\"/api/polly8/RandomException\");\n", - " response.EnsureSuccessStatusCode();\n", - " var content = await response.Content.ReadAsStringAsync();\n", - "\n", - " Console.WriteLine($\"响应内容:{content}\");\n", + " try\n", + " {\n", + " var factory = services.BuildServiceProvider().GetService();\n", + " var content = await factory.CreateClient().GetStringAsync(\"/api/polly8/RandomException\");\n", + " Console.WriteLine($\"响应内容:{content}\");\n", + " }\n", + " catch(Exception ex)\n", + " {\n", + " Console.WriteLine($\"未处理的异常:{ex.Message}\");\n", + " }\n", "}" ] }, @@ -1891,6 +1941,13 @@ "### 动态选择策略" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 从注册表中选择策略" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs b/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs index 350323c..666b7bc 100644 --- a/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs +++ b/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs @@ -25,6 +25,16 @@ namespace HttpClientStudy.WebApp.Controllers _logger = logger; } + /// + /// 异常接口 + /// + /// + [HttpGet] + public ActionResult Exception() + { + throw new HttpRequestException("服务器异常"); + } + /// /// 重试策略异常 ///