【发布时间】:2017-11-27 20:58:09
【问题描述】:
我有一个准系统 Service Fabric 应用程序,它在 5 个 DS3_V2 的虚拟机规模集上托管 Asp.net Core 1.1 Web API,并将 Azure 应用程序网关作为反向代理。
API 有 10 个 HttpClient,它们通过依赖注入注入不同的 URL。 一个方法中的简单foreach循环并行调用10个Httpclient:
var cts = new CancellationTokenSource();
cts.CancelAfter(600);
//Logic for asyncronously parallel calling the Call method below
public async Task<MyResponse> Call(CancellationTokenSource cts, HttpClient client, string endpoint )
{
var endpoint = "finalpartOfThendpoint";
var jsonRequest = "jsonrequest";
try
{
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
await content.LoadIntoBufferAsync();
if (cts.Token.IsCancellationRequested)
{
return new MyResponse("Token Canceled");
}
var response = await client.PostAsync(endpoint, content, cts.Token);
if (response.IsSuccessStatusCode && ((int)response.StatusCode != 204))
{
//do something with response and return
return MyResponse("Response Ok")
}
return MyResponse("No response")
}
catch (OperationCanceledException e)
{
return new MyResponse("Timeout");
}
}
所有调用都有一个 CancellationToken。 600 毫秒后,仍然挂起的 HttpCall 被取消,并且无论如何都会发回响应。 在本地和生产中一切正常,所有端点都被调用并及时返回,很少有一个在超时之前被取消。
但是当并发连接数达到30+时,ALL调用超时无论如何,直到我减少负载。
Asp.net Core 有连接限制吗?
这就是我在自定义工厂中创建 HttpClients 以在主控制器中注入的方式:
public static HttpClient CreateClient(string endpoint)
{
var client = new HttpClient
{
BaseAddress = new Uri(endpoint)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
所有的 Httpclients 都被重用并且是静态的。 完全相同的代码在 Service Fabric 中的 OWIN 上托管的 Asp.net Web API 2 上完美运行。问题仅出在 Asp.net Core 1.1
看到网上创建了一个HttpClientHandler,但是没有并发连接的参数。
我可以做些什么来进一步调查? 没有抛出异常,但 OperationcanceledException 和 如果我删除 CancellationToken 调用会卡住并且 CPU 达到 100%,基本上 30 个连接会破坏 5 个四核服务器的能力。
这与从 Kestrel 发出的呼叫数量有关。
更新
我用 WebListener 试过了,问题依然存在,所以不是 Kestrel,而是 Asp.net Core
【问题讨论】:
-
您的所有 httpclients 都使用相同的端点还是为每个客户端创建一个端点?
标签: asp.net-core asp.net-core-mvc azure-service-fabric asp.net-core-webapi kestrel-http-server