【问题标题】:14s delay with HttpClient and PollyHttpClient 和 Polly 延迟 14 秒
【发布时间】:2018-12-06 02:27:03
【问题描述】:

我正在使用 httpClient 执行 POST 请求。我正在使用 Polly 进行重试。发生的情况是第一次尝试需要 14 秒,即使我指定了 2 秒的重试时间。第一次尝试在 14 秒后失败,然后有 2 秒的差距,直到第二次尝试。我希望它每 2 秒尝试一次并超时并重试任何错误。这是正确的做法吗?

            var retryPolicy = Policy
                .Handle<Exception>()    // retry on any
                .WaitAndRetryAsync(6, 
                    retryAttempt => TimeSpan.FromMilliseconds(2000), 
                    (response, calculatedWaitDuration, ctx) =>
                    {
                        Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
                    });
            HttpResponseMessage httpResp = null;
            await retryPolicy.ExecuteAsync(async () =>
            {
                httpResp = await DoPost();
                httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
                return httpResp;
            });


            var respBody = await httpResp.Content.ReadAsStringAsync();
            return respBody;

            async Task<HttpResponseMessage> DoPost()
            {
                var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url)
                {
                    Content = new StringContent(json, Encoding.UTF8, Constants.JsonContentType),
                    Headers = { Authorization = await GetAuthenticationTokenAsync() }
                };
                ServicePointManager.Expect100Continue = false;
                var httpResponseMessage = await StaticHttpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
                return httpResponseMessage;
            }

【问题讨论】:

    标签: httpclient polly


    【解决方案1】:

    第一次尝试需要 14 秒,尽管我指定了 2 秒的重试时间。 第一次尝试在 14 秒后失败,然后有 2 秒的差距,直到第二次尝试。

    没错。 WaitAndRetry 是关于在失败后等待多长时间,然后重试,如specified in the documentation

    我希望它每 2 秒尝试一次并超时并重试任何错误。

    要强制超时,请使用 Polly 的 Timeout policy。要同时施加超时和重试,请使用 PolicyWrap 结合超时和 Retry 策略。因此,您可以像这样调整您的代码:

            var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(2000));
    
            var retryPolicy = Policy
                .Handle<Exception>()    // retry on any
                .WaitAndRetryAsync(6,  // or just RetryAsync() if you don't want any wait before retrying
                    retryAttempt => /* a timespan, _if you want a wait before retrying */, 
                    (response, calculatedWaitDuration, ctx) =>
                    {
                        Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
                    });
    
            var combinedPolicy = retryPolicy.WrapAsync(timeoutPolicy);
    
            HttpResponseMessage httpResp = null;
            await combinedPolicy.ExecuteAsync(async () =>
            {
                httpResp = await DoPost();
                httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
                return httpResp;
            });
    

    有关更多讨论和示例,请参阅this similar stackoverflow question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 2013-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多