我已经在解决方案中使用.net core 3.1和Polly 7.2.0实现了Polly。我已经为IServiceCollection创建了扩展,并且在我的启动文件中,我正在调用这些扩展来配置和添加客户端,还创建策略并进行注册。
在我的ExternalClient类中,我正在使用IHttpClientFactory消耗我的客户端,并且使用IAsyncPolicy策略将调用与我在Startup上创建并设置的策略包装在一起。
Startup.cs
...
services.AddHttpClients(Configuration);
services.AddRetryPolicy(Configuration);
...
ServiceCollectionExtension.cs
...
var policy = Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(retryCount), (exception, timeSpan, count,
context) =>
{
LogTo.Error($"Failed while posting to {myClient.Host}, retrying: " +
$"{count} of {retryCount} in " +
$"{timeSpan.TotalSeconds} seconds, with exception " +
$"{exception.Message}");
});
services.AddHttpClient("MyClient", c => { c.BaseAddress = new Uri(myClient.Host); })
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
{
Credentials = credentialsCache
});
...
ExternalClient
...
try
{
var response = await _policy
.ExecuteAsync(async () => (await _client.PostAsync(endpoint, requestBody)).EnsureSuccessStatusCode())
.ConfigureAwait(false);
return response.StatusCode == HttpStatusCode.OK;
}
catch (Exception ex)
{
LogTo.Error(ex, "Unable to contact Myclient");
}
...
该策略的执行正常,下一步是检查是否有一种方法可以为我的客户端添加故障转移URL。我已经检查了Polly的documentation,也看到了WebClient的this方法,但是如果策略和实现位于同一位置,则可以使用该方法。我相信,如果我有一个http客户端调用发生在一种方法中,可以用ExecuteAsync包装到该调用,然后提供不同的客户端,那么这样做是可能的,但我当时正在寻找一种更优雅的解决方案,也许它在那里我不知道。
作为covered in other questions,System.Net.Http.HttpClient
并非为更改BaseAddress
而设计。
但是,您不必使用不同的HttpClient
实例以具有不同基地址的URI为目标。您根本无法在您配置的BaseAddress
上设置HttpClient
属性,而是在通过单个HttpClient
实例进行的调用中使用完全限定的URI(例如,在主URI和故障转移URI之间进行切换)。