我正在尝试使用Polly测试连接字符串是否为null。如果为空,我想使用CircuitBreaker尝试三遍,并且该消息应该在控制台窗口中输出。
Policy policy = null;
// Break the circuit after the specified number of exceptions
// and keep circuit broken for the specified duration.
policy = Policy
.Handle<NullReferenceException>()
.CircuitBreaker(3, TimeSpan.FromSeconds(30));
try
{
string connected = policy.Execute(() => repository.GetConnectionString());
}
catch (Exception ex)
{
Console.WriteLine("{0}",ex.Message);
}
Run Code Online (Sandbox Code Playgroud)
和GetConnectionString方法是:
public string GetConnectionString()
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["Test1"].ConnectionString;
return conn.ConnectionString;
}
Run Code Online (Sandbox Code Playgroud)
为了对此进行测试,我在App.config中更改了连接字符串名称。
但是,它似乎没有处理NullReference Exception。
当我调试应用程序时-它将打开未找到的CircuitBreakerEngine.cs并仅打印“对象引用未设置为对象的实例”。
预期的:从断路异常中打印未将对象引用设置为对象实例三次的消息
如何执行多个策略(或将它们合并为一个策略)?
例如我有:
var policy1 = Policy.Handle< DivideByZeroException >().WaitAndRetry(5));
var policy2 = Policy.Handle< StackOverflowException >().RetryForever();
Run Code Online (Sandbox Code Playgroud)
如何同时将它们应用于一种方法?
I have gone through the documentation and examples of Polly Framework, and it's really awesome and simple to use !!
In my case, I want to classify all the exceptions into 3 types: temporary, permanent and log. Now, I want to have a single piece of code which will be responsible to handle errors which are temporary in nature by doing wait and retry using Polly Framework.
WaitAndRetryAsync(new[]{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(5)
})
Run Code Online (Sandbox Code Playgroud)
Same way, if something is permanent in nature …
我有一个服务 AAA,每分钟向 RabbitMQ 交换发布 10 到 5 万条消息。.NET Core 服务 BBB 订阅一个队列(所有消息都路由到该队列),并为每条消息调用另一个通过 Internet 的 HTTP 服务 CCC。问题是 CCC 非常不可靠,每天有几次它会完全关闭一两分钟,每周至少有一次它会关闭一个小时。
我无法控制 AAA 或 CCC。如何使用 RabbitMQ 路由功能可靠地传递所有消息?
unreliable-connection rabbitmq reliable-message-delivery polly retry-logic
I\xe2\x80\x98m 使用 polly 对 HTTP POST 请求进行简单的重试 n 次 szenario。它应该处理任何异常并重试将我的负载发送到 api 端点 n 次。因此,我使用了 WaitAndRetryPolicy 来包装 TimoutPolicy,并采用悲观策略来实现每次尝试超时。两者都是异步策略。
\n\n当重试情况发生时,所做的每次重试尝试都会在重新建立连接后发布到端点。
\n\n封装这两个策略的方法:
\n\n\n public static PolicyWrap WaitAndRetryNTimesWithTimeoutPerTry(int n, TimeSpan sleepDuration, TimeSpan retryTimeout)\n {\n var waitAndRetryPolicy = Policy.Handle<Exception>().WaitAndRetryAsync(\n retryCount: n,\n sleepDurationProvider: attempt => sleepDuration,\n onRetry: (exception, waitDuration, ctx) =>\n {\n Debug.WriteLine($"[Polly.OnRetry due \'{exception.Message}\'; waiting for {waitDuration.TotalMilliseconds} ms before retrying.");\n }\n );\n\n var timeoutPerTryPolicy = Policy.TimeoutAsync(\n retryTimeout, TimeoutStrategy.Pessimistic);\n\n return waitAndRetryPolicy.WrapAsync(timeoutPerTryPolicy);\n }\nRun Code Online (Sandbox Code Playgroud)\n\n调用Web api的代码:
\n\n\n var waitAndRetry5TimesWithShortTimeout = ResiliencePolicyFactory.WaitAndRetryNTimesWithTimeoutPerTry(\n …Run Code Online (Sandbox Code Playgroud) .NET 版本:.NET Framework 4.6.1
Polly 版本:7.2.2
在 .NET Framework 4.6.1 上,当使用 Web API 项目时,Polly 将无限期等待正在运行请求的线程,从而导致永远不会对调用它的客户端进行响应。从控制台应用程序调用相同的方法将工作得很好。
这是使用 Visual Studio 'ASP.NET Web Application (.NET Framework)' 中新创建的解决方案进行测试的。我也在 .NET 5 中尝试了同样的代码,但这个问题不存在,它只发生在 .NET Framework 4.6.1 上。
重现问题的代码:
策略容器.cs:
public class PolicyContainer
{
public IAsyncPolicy<HttpResponseMessage> CircutBreakerPolicy { get; set; }
public PolicyContainer()
{
SetCircutBreakerPolicy();
}
private void SetCircutBreakerPolicy()
{
//////////////////////////////////////////////////////////////////////////////////////
// Normally these values would be set by a config file, hardcoded for this example. //
//////////////////////////////////////////////////////////////////////////////////////
// 0.5 means 50% of requests must fail …Run Code Online (Sandbox Code Playgroud) 我试图让 Polly 在 3 秒后超时以及返回某些 http 代码时再次尝试。但是,直到 100 秒后 HttpClient 超时后才会超时。
这是我的代码:
private static Polly.Wrap.AsyncPolicyWrap<HttpResponseMessage> GetPolicy()
{
var timeoutPolicy = Policy.TimeoutAsync(3, Polly.Timeout.TimeoutStrategy.Optimistic);
var retryPolicy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r =>
r.StatusCode == HttpStatusCode.TooManyRequests ||
r.StatusCode == HttpStatusCode.ServiceUnavailable ||
r.StatusCode == HttpStatusCode.Forbidden)
.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(3));
var policy = retryPolicy.WrapAsync(timeoutPolicy);
return policy;
}
Run Code Online (Sandbox Code Playgroud)
更新
根据要求,这是我使用该策略的代码。
var pollyResponse = await GetPolicy().ExecuteAndCaptureAsync(() =>
httpClient.SendAsync(GetMessage(HttpMethod.Delete, endpoint))
);
Run Code Online (Sandbox Code Playgroud)
以及生成 HttpRequestMessage 的辅助方法:
private HttpRequestMessage GetMessage<T>(HttpMethod method, string endpoint, T content)
{
var message = new HttpRequestMessage
{ …Run Code Online (Sandbox Code Playgroud) 注册服务:
var host = new HostBuilder().ConfigureServices(services =>
{
services.AddHttpClient<Downloader>(client =>
{
client.Timeout = TimeSpan.FromSeconds(1); // -- T1
})
.AddPolicyHandler(HttpPolicyExtensions
.HandleTransientHttpError()
.Or<HttpRequestException>()
.WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(
TimeSpan.FromSeconds(5), // -- T2
retryCount: 3)))
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(10)) // -- T3
.AddPolicyHandler(HttpPolicyExtensions
.HandleTransientHttpError()
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30))); // -- T4
services.AddTransient<Downloader>();
}).Build();
Run Code Online (Sandbox Code Playgroud)
实施Downloader:
class Downloader
{
private HttpClient _client;
public Downloader(IHttpClientFactory factory)
{
_client = factory.CreateClient();
}
public void Download(List<Uri> links)
{
await Parallel.ForEachAsync(
links,
async (link, _cancelationToken) =>
{
await _client.GetStreamAsync(uri, _cancellationToken);
});
}
}
Run Code Online (Sandbox Code Playgroud)
在此伪代码中,我对超时之间的相关性以及如何/何时重新提交 HTTP 请求感到困惑。具体来说: …
我正在尝试设置一个 IHttpClientFactory,我想知道如何在创建时向它发送参数,这些参数我需要分配给重试策略。
我正在使用 .Net Core 2.2 和 Microsoft.Extensions.Http.Polly,我已经阅读了这篇文章https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore -2.2
我有这是 Startup.cs
services.AddHttpClient("MyClient", c =>
{
c.BaseAddress = new Uri("http://interface.net");
c.DefaultRequestHeaders.Add("Accept", "application/json");
})
.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));
Run Code Online (Sandbox Code Playgroud)
我是这样用的
private readonly IHttpClientFactory _iHttpClientFactory;
public ValuesController(IHttpClientFactory iHttpClientFactory)
{
_iHttpClientFactory = iHttpClientFactory;
}
public async Task<ActionResult<string>> Get()
{
var client = _iHttpClientFactory.CreateClient("MyClient");
var response = await client.GetAsync("/Service?Id=123");
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
return result;
}
Run Code Online (Sandbox Code Playgroud)
我想知道在执行 CreateClient 时是否有一种方法可以发送参数,以便在 AddTransientHttpErrorPolicy 中分配给 retryCount 和 sleepDuration,在这种情况下分别为 3 和 600,因为我需要创建具有不同 retryCounts 和 sleepDurations 的客户端和这些值可以改变。 …
我有一个.tgz文件,我需要下载一个Testing文件夹内的 url 。我可以.tgz使用 .url 从 url 成功下载文件WebClient。
下面是我的代码:
private void DownloadTGZFile(string url, string fileToDownload)
{
using (var client = new WebClient())
{
client.DownloadFile(url + fileToDownload, "Testing/configs.tgz");
}
}
Run Code Online (Sandbox Code Playgroud)
我想看看如何为这个调用添加超时,以便如果 url 在特定时间内没有响应,那么它应该超时但它可以重试 3 次然后放弃。另外我想看看我如何HttpClient在这里使用而不是WebClient考虑它是一个较旧的 BCL 类而不推荐。
我有以下代码:
var policyResult = await _circuitBreakerPolicy.ExecuteAndCaptureAsync(async () =>
{
return await configuredTaskAwaitable;
});
return policyResult.Result;
Run Code Online (Sandbox Code Playgroud)
当断路器处于Open状态时,结果只是null,并且不会抛出异常。如果电路打开,它不应该抛出异常吗?
当出现 HttpRequestException、5XX 和 408 错误时,下面的代码重试 2 次,并且工作正常。
这里我想重试一下是否有401错误?我们如何通过 Polly 实现这一目标?
services.AddHttpClient(Options.DefaultName)
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { })
.AddPolicyHandler(HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))));
Run Code Online (Sandbox Code Playgroud) polly ×12
c# ×9
retry-logic ×3
.net ×2
asp.net-core ×2
timeout ×2
.net-core ×1
oop ×1
rabbitmq ×1