Service Fabric Asp.net Core Kestrel HttpClient 以最小负载挂起
Service Fabric Asp.net Core Kestrel HttpClient hangs with minimal load
我有一个准系统 Service Fabric 应用程序托管 Asp.net Core 1.1 Web API,Azure 应用程序网关作为虚拟机规模集 5 DS3_V2 的反向代理。
API 有 10 个 HttpClient,它们通过依赖注入注入了不同的 URL。
方法中的一个简单的 foreach 循环并行调用 10 个 Httpclients:
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 毫秒后,仍然挂起的 HttpCalls 将被取消,并且无论如何都会发回响应。
在本地和生产中,一切都完美无缺,所有端点都被调用并及时return,很少有人在超时前被取消。
但是当并发连接数达到30+时,ALL调用timeout无论如何,直到我减轻负载。
Asp.net核心是否有连接限制?
这就是我在自定义工厂中创建 HttpClient 以便在主控制器中注入的方式:
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
我想通了。
Asp.net 核心对于与旧 Asp.net WebAPI 相同的服务器的连接仍然有一些 HttpClient 限制。
它的记录很差,但是 maxconnections 的旧 ServicepointManager 选项现在必须通过 HttpClientHandler 传递。
我只是像这样创建 HttpClient,问题就消失了。
var config = new HttpClientHandler()
{
MaxConnectionsPerServer = int.MaxValue
};
var client = new HttpClient(config)
{
BaseAddress = new Uri('url here')
};
真的,如果团队中有人正在阅读,这应该是默认设置。
我有一个准系统 Service Fabric 应用程序托管 Asp.net Core 1.1 Web API,Azure 应用程序网关作为虚拟机规模集 5 DS3_V2 的反向代理。
API 有 10 个 HttpClient,它们通过依赖注入注入了不同的 URL。 方法中的一个简单的 foreach 循环并行调用 10 个 Httpclients:
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 毫秒后,仍然挂起的 HttpCalls 将被取消,并且无论如何都会发回响应。 在本地和生产中,一切都完美无缺,所有端点都被调用并及时return,很少有人在超时前被取消。
但是当并发连接数达到30+时,ALL调用timeout无论如何,直到我减轻负载。
Asp.net核心是否有连接限制?
这就是我在自定义工厂中创建 HttpClient 以便在主控制器中注入的方式:
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
我想通了。
Asp.net 核心对于与旧 Asp.net WebAPI 相同的服务器的连接仍然有一些 HttpClient 限制。 它的记录很差,但是 maxconnections 的旧 ServicepointManager 选项现在必须通过 HttpClientHandler 传递。 我只是像这样创建 HttpClient,问题就消失了。
var config = new HttpClientHandler()
{
MaxConnectionsPerServer = int.MaxValue
};
var client = new HttpClient(config)
{
BaseAddress = new Uri('url here')
};
真的,如果团队中有人正在阅读,这应该是默认设置。