0
public static IAsyncPolicy<HttpResponseMessage> GetSaveExceptionPolicy(
            IServiceProvider serviceProvider)
{

    return Policy
        .HandleResult<HttpResponseMessage>(x => x.StatusCode == HttpStatusCode.Forbidden)
        .FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK),
            d =>
            {
                var mediator = serviceProvider.GetService<IMediatorService>();
                mediator.SaveFailedOnInvalidLock();
                return Task.CompletedTask;
            });
}
 serviceCollection
    .AddHttpClient<IMyClient, MyClient>(p =>
    {
        p.BaseAddress = baseAddress;
        p.Timeout = TimeSpan.FromMinutes(10);
        
    })
    .ConfigurePrimaryHttpMessageHandler(sp => new HttpClientHandler() { MaxConnectionsPerServer = 10})
    .AddPolicyHandler((serviceProvider, request) => GetSaveExceptionPolicy(serviceProvider));

这是调解员电话

public void SaveFailedOnInvalidLock()
{
    _logger.Error($"Data Point Saving failed");
    SaveFailedOnInvalidLock?.Invoke();
}

这个 MyClient Post 方法被非常频繁地调用。例如,在给定的一秒内,有 7 个呼叫正在进行。并且每秒钟有 7 个在继续。

应用程序工作正常,直到 Post 方法返回“HttpStatusCode.Forbidden”。当它返回 Forbidden 时,一些下一个调用不会到达 REST 端点。

这是由于某些连接不可用吗?例如:由于“fobidden”状态和 polly 后备策略而丢失的连接很少?(因为最大限制是 10)?

或者这是由于 Async 及其时间安排使得当第二批呼叫进来时连接仍在使用中?

提前致谢

4

1 回答 1

0

我能够通过在回退操作中返回相同的 http 响应消息来解决这个问题(而不是创建一个新的 HTTPResponseMessage)

我想因为我有MaxConnectionsPerServer = 10 并且我在给定的时刻使用了其中的 7 个,如果我返回的话new HttpResponseMessage(HttpStatusCode.OK),会有一些处理程序没有被处理或卡住。

这是我的新政策

public static AsyncFallbackPolicy<HttpResponseMessage> GetDataPointSaveExceptionPolicy(
    IServiceProvider serviceProvider)
{
   return Policy 
       .HandleResult<HttpResponseMessage>(x=>
           x.StatusCode ==  HttpStatusCode.Forbidden)
       .FallbackAsync(
           (res, cx, ct) =>
           {
               var dataServiceMediator = serviceProvider.GetService<IDataServiceMediatorService>();
               dataServiceMediator.DataPointSaveFailedOnInvalidLock();

               return Task.FromResult(res.Result); 
           },
           (ct, cx) => Task.CompletedTask);
}

这将返回Task.FromResult(res.Result)并且没有处理问题并且对MyClient继续到达 REST 端点的调用。

于 2021-03-31T02:28:30.340 回答