main
bicijinlian 6 months ago
parent 9a978d7453
commit 5467df9657

@ -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

@ -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<HttpResponseMessage>());\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<IHttpClientFactory>();\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<HttpResponseMessage>();\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<IHttpClientFactory>();\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<IHttpClientFactory>();\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": {},

@ -9,17 +9,17 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.KeyPerFile" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.KeyPerFile" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.1.0" />

@ -12,7 +12,7 @@ namespace HttpClientStudy.WebApp.Controllers
[ApiController]
public class Polly8Controller : ControllerBase
{
private static ConcurrentDictionary<string,bool> ToggleExceptionCache = new ConcurrentDictionary<string,bool>();
private static ConcurrentDictionary<string, bool> ToggleExceptionCache = new ConcurrentDictionary<string, bool>();
private readonly ILogger<Polly8Controller> _logger;
@ -21,10 +21,20 @@ namespace HttpClientStudy.WebApp.Controllers
/// </summary>
/// <param name="logger">日志</param>
public Polly8Controller(ILogger<Polly8Controller> logger)
{
{
_logger = logger;
}
/// <summary>
/// Polly8Hello
/// </summary>
/// <returns></returns>
[HttpGet]
public ActionResult Hello()
{
return Ok("Polly v8");
}
/// <summary>
/// 异常接口
/// </summary>
@ -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
/// </summary>
/// <returns></returns>
[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}");
}
}
}

@ -1,5 +1,5 @@
{
"urls": "http://localhost:5189",
"urls": "http://192.168.20.46:5189",
"Logging": {
"LogLevel": {
"Default": "Information",

Loading…
Cancel
Save