From 5467df9657b8b0a022b9eebb364afa0e1ce3f99e Mon Sep 17 00:00:00 2001 From: bicijinlian Date: Mon, 12 Aug 2024 20:36:00 +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.0项目管理.dib | 2 + Docs/1.3.0.基础使用.管理客户端.ipynb | 145 +++++++++++++++++- .../HttpClientStudy.Config.csproj | 8 +- .../Controllers/Polly8Controller.cs | 25 ++- HttpClientStudy.WebApp/appsettings.json | 2 +- 5 files changed, 168 insertions(+), 14 deletions(-) diff --git a/Docs/1.0项目管理.dib b/Docs/1.0项目管理.dib index c366b4e..76d35e2 100644 --- a/Docs/1.0项目管理.dib +++ b/Docs/1.0项目管理.dib @@ -32,6 +32,8 @@ dotnet publish ..\HttpClientStudy.Service\HttpClientStudy.Service.csproj -c Rele dotnet publish ..\HttpClientStudy.WebApp\HttpClientStudy.WebApp.csproj -c Release -o .\Publish\HttpClientStudy.WebApp dotnet publish ..\HttpClientStudy.WebClient\HttpClientStudy.WebClient.csproj -c Release -o .\Publish\HttpClientStudy.WebClient +Write-Host "发布结束!" + #!markdown ## 启动WebApi diff --git a/Docs/1.3.0.基础使用.管理客户端.ipynb b/Docs/1.3.0.基础使用.管理客户端.ipynb index 61fee7e..25e9830 100644 --- a/Docs/1.3.0.基础使用.管理客户端.ipynb +++ b/Docs/1.3.0.基础使用.管理客户端.ipynb @@ -95,6 +95,7 @@ "global using Polly.Wrap;\n", "global using Polly.Registry;\n", "global using Polly.Telemetry;\n", + "global using Polly.Extensions.Http;\n", "\n", "global using Refit;\n", "//global using Refit.HttpClientFactory;\n", @@ -1884,7 +1885,7 @@ "\n", " services\n", " .AddHttpClient(\"timeoutPolicy2\")\n", - " //转换通用策略\n", + " //AsAsyncPolicy转换通用策略\n", " .AddPolicyHandler(timeoutPolicy2.AsAsyncPolicy());\n", "}\n", "\n", @@ -1934,6 +1935,59 @@ "### 应用多个策略" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "outputs": [], + "source": [ + "{\n", + " var services = new ServiceCollection();\n", + "\n", + " services.AddHttpClient(string.Empty)\n", + " .ConfigureHttpClient(client => \n", + " {\n", + " client.BaseAddress = new Uri(webApiBaseUrl);\n", + " })\n", + " .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync\n", + " (\n", + " new[]\n", + " {\n", + " TimeSpan.FromSeconds(1),\n", + " TimeSpan.FromSeconds(2),\n", + " TimeSpan.FromSeconds(3),\n", + " }\n", + " ))\n", + " //断路器\n", + " .AddTransientHttpErrorPolicy(builder => builder.CircuitBreakerAsync(\n", + " handledEventsAllowedBeforeBreaking: 3,\n", + " durationOfBreak: TimeSpan.FromSeconds(30)\n", + " ));\n", + "\n", + " try\n", + " {\n", + " var factory = services.BuildServiceProvider().GetRequiredService();\n", + " var content = await factory.CreateClient().GetStringAsync(\"/api/polly8/RandomException\");\n", + " Console.WriteLine(content);\n", + " }\n", + " catch(Exception ex)\n", + " {\n", + "\n", + " Console.WriteLine(\"API异常:\"+ex.Message);\n", + " }\n", + "}" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1941,6 +1995,48 @@ "### 动态选择策略" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "outputs": [], + "source": [ + "//实质是AddPolicyHandler中选择一个策略\n", + "{\n", + " var retryPolicy = Polly.Extensions.Http.HttpPolicyExtensions\n", + " .HandleTransientHttpError()\n", + " .WaitAndRetryAsync(new[]\n", + " {\n", + " TimeSpan.FromSeconds(1),\n", + " TimeSpan.FromSeconds(2),\n", + " TimeSpan.FromSeconds(4)\n", + " });\n", + " var noOpPolicy = Policy.NoOpAsync().AsAsyncPolicy();\n", + "\n", + " var services = new ServiceCollection();\n", + " services.AddHttpClient(string.Empty, client =>\n", + " {\n", + " client.BaseAddress = new Uri(webApiBaseUrl);\n", + " })\n", + " // 根据请求方法,选择策略\n", + " .AddPolicyHandler(request => request.Method == HttpMethod.Get ? retryPolicy : noOpPolicy);\n", + "\n", + " var factory = services.BuildServiceProvider().GetRequiredService();\n", + " var client1 = factory.CreateClient(string.Empty);\n", + " var content1 = await client1.GetStringAsync(\"/api/hello/get\");\n", + " Console.WriteLine(content1);\n", + "\n", + " var client2 = factory.CreateClient(string.Empty);\n", + " var response2 = await client2.PostAsync(\"/api/hello/post\",null);\n", + " var content2 = await response2.Content.ReadAsStringAsync();\n", + " Console.WriteLine(content2);\n", + "}" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1948,6 +2044,53 @@ "### 从注册表中选择策略" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "outputs": [], + "source": [ + "{\n", + " var registry = new PolicyRegistry()\n", + " {\n", + " { \"defaultretrystrategy\", HttpPolicyExtensions.HandleTransientHttpError().WaitAndRetryAsync(new TimeSpan[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3)}) },\n", + " { \"defaultcircuitbreaker\", HttpPolicyExtensions.HandleTransientHttpError().CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)) },\n", + " };\n", + "\n", + " var services = new ServiceCollection();\n", + " services.AddPolicyRegistry(registry);\n", + "\n", + " services.AddHttpClient(\"a\", client => { client.BaseAddress = new Uri(webApiBaseUrl); })\n", + " .AddPolicyHandlerFromRegistry(\"defaultretrystrategy\")\n", + " //.AddPolicyHandlerFromRegistry(\"defaultcircuitbreaker\")\n", + " ;\n", + "\n", + " services.AddHttpClient(\"b\", client => { client.BaseAddress = new Uri(webApiBaseUrl); })\n", + " //.AddPolicyHandlerFromRegistry(\"defaultretrystrategy\")\n", + " .AddPolicyHandlerFromRegistry(\"defaultcircuitbreaker\")\n", + " ;\n", + "\n", + " var factory = services.BuildServiceProvider().GetService();\n", + " var clientA = factory.CreateClient(\"a\");\n", + " var clientB = factory.CreateClient(\"b\");\n", + "\n", + " try\n", + " {\n", + " var resultA = await clientA.GetStringAsync(\"/api/polly8/exception\");\n", + " }\n", + " catch (Exception ex)\n", + " {\n", + " Console.WriteLine(ex.Message);\n", + " }\n", + " \n", + " var resultB = await clientB.GetStringAsync(\"/api/polly8/hello\");\n", + "}" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/HttpClientStudy.Config/HttpClientStudy.Config.csproj b/HttpClientStudy.Config/HttpClientStudy.Config.csproj index d2b277e..815446e 100644 --- a/HttpClientStudy.Config/HttpClientStudy.Config.csproj +++ b/HttpClientStudy.Config/HttpClientStudy.Config.csproj @@ -9,17 +9,17 @@ - + - + - + - + diff --git a/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs b/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs index 666b7bc..718c6b2 100644 --- a/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs +++ b/HttpClientStudy.WebApp/Controllers/Polly8Controller.cs @@ -12,7 +12,7 @@ namespace HttpClientStudy.WebApp.Controllers [ApiController] public class Polly8Controller : ControllerBase { - private static ConcurrentDictionary ToggleExceptionCache = new ConcurrentDictionary(); + private static ConcurrentDictionary ToggleExceptionCache = new ConcurrentDictionary(); private readonly ILogger _logger; @@ -21,10 +21,20 @@ namespace HttpClientStudy.WebApp.Controllers /// /// 日志 public Polly8Controller(ILogger logger) - { + { _logger = logger; } + /// + /// Polly8Hello + /// + /// + [HttpGet] + public ActionResult Hello() + { + return Ok("Polly v8"); + } + /// /// 异常接口 /// @@ -42,7 +52,6 @@ namespace HttpClientStudy.WebApp.Controllers [HttpGet] public ActionResult RetryException() { - //return BadRequest("服务器异常"); throw new HttpRequestException("服务器异常"); } @@ -53,12 +62,12 @@ namespace HttpClientStudy.WebApp.Controllers [HttpGet] public ActionResult RandomException() { - var num = Random.Shared.Next(1,100); + var num = Random.Shared.Next(1, 100); if (num >= 50) { throw new HttpRequestException("服务器随机异常"); } - else + else { return Ok(num); } @@ -69,7 +78,7 @@ namespace HttpClientStudy.WebApp.Controllers /// /// [HttpGet] - public ActionResult ToggleException(string toggleId="") + public ActionResult ToggleException(string toggleId = "") { var toggle = ToggleExceptionCache.GetOrAdd(toggleId, true); //保存切换 @@ -80,8 +89,8 @@ namespace HttpClientStudy.WebApp.Controllers throw new HttpRequestException("服务器随机异常"); } else - { - return Ok($"toggleId={toggleId}"); + { + return Ok($"ToggleException toggleId={toggleId}"); } } } diff --git a/HttpClientStudy.WebApp/appsettings.json b/HttpClientStudy.WebApp/appsettings.json index 5585347..d96cb05 100644 --- a/HttpClientStudy.WebApp/appsettings.json +++ b/HttpClientStudy.WebApp/appsettings.json @@ -1,5 +1,5 @@ { - "urls": "http://localhost:5189", + "urls": "http://192.168.20.46:5189", "Logging": { "LogLevel": { "Default": "Information",