问题描述
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 端点。
这是因为某些连接不可用吗?例如:由于“禁止”状态和波利回退策略,很少有连接丢失? (因为最大限制是 10)?
或者这是由于 Async 及其时序导致第二批调用进入时连接仍在使用中?
提前致谢
解决方法
我能够通过在回退操作中返回相同的 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 端点。