.Net 7的HTTPClient请求每6分钟响应时间较慢。

huangapple go评论67阅读模式
英文:

.Net 7 slow response times from HTTPClient request every 6 minutes

问题

We are experiencing an issue with HTTP requests where we are seeing that every 6 minutes a HTTP request is taking up to 162ms, on average these requests are taking 7ms. The metrics graph below shows a brief run of a K6 script calling our controller at a rate of 36 requests/minute. Im running K6 locally and both services in question are an AWS ECS instances. The slow response pattern persists for as long as I leave K6 running at this rate. The more you increase the rate at which K6 sends requests the less noticeable the spikes in the requestduration metric. I have metrics around the API controller which I am calling and they are showing an average time taken of 2ms so this is not the issue.

我们遇到了一个HTTP请求的问题,每6分钟一次的HTTP请求平均需要162毫秒,通常这些请求只需要7毫秒。下面的度量图显示了一个K6脚本以每分钟36个请求的速度调用我们的控制器的简要运行情况。我在本地运行K6,而涉及的两个服务都是AWS ECS实例。在这个速率下,只要我让K6运行,慢响应模式就会持续存在。增加K6发送请求的速率,请求持续时间指标中的波动就会变得不太明显。我有关于我调用的API控制器的度量,它们显示平均耗时为2毫秒,所以这不是问题所在。

I initially thought this might be to do with the PooledConnectionIdleTimeout, but the default value for this is 1 minute in .NET 6 and later versions. We are using .Net 7. Not seeing anything on our infrastructure which would cause these spikes either.

我最初认为这可能与PooledConnectionIdleTimeout有关,但在.NET 6及以后版本中,其默认值为1分钟。我们使用的是.NET 7。我们的基础架构上也没有看到任何可能引起这些波动的东西。

My question is has anyone seen similar behaviour making HTTP requests, is it a possible issue with the code below?

我的问题是是否有人看到过类似的HTTP请求行为,下面的代码可能有问题吗?

We are adding our HTTP Client to our IServiceCollection as follows:

我们将HTTP客户端添加到IServiceCollection中,如下所示:

_builder.Services.AddHttpClient<IHttpClient, HttpClient>();

Our HTTP Client is as follows

我们的HTTP客户端如下所示:

public class HttpClient : IHttpClient
{
    private readonly Metric.Client.IRecorder c_metrics;
    private readonly System.Net.Http.HttpClient c_httpClient;
    
    public HttpClient(
        Metric.Client.IRecorder metrics,
        System.Net.Http.HttpClient httpClient)
    {
        this.c_httpClient = httpClient;
    }

    public async Task<HttpResponseMessage> GetAsync(
        string requestUrl,
        string correlationId)
    {
        using (var _request = new HttpRequestMessage(HttpMethod.Get, requestUrl))
        {
            _request.Headers.Add("X-CorrelationId", correlationId);
            
            using var _timer = this.c_metrics.StartTimer("requestduration");
            return await this.c_httpClient.SendAsync(_request);
        }
    }
}

Our controller which we get our HttpClient from our DI container

我们的控制器从DI容器中获取HttpClient的方式如下:

public Controller(
    IHttpClient httpClient)
{
    this.c_httpClient = httpClient;
}

public async Task<IActionResult> GetAsync(
    [FromQuery] Request request)
{
    var _privateResponse = await this.c_httpClient.GetAsync(_requestUrl, _correlationId);

    if (_privateResponse.StatusCode != HttpStatusCode.OK)
    {
        return StatusCode(500, new Error(Guid.Parse(_correlationId), "Internal server error"));
    }

    var _privateResponseContent = await _privateResponse.Content.ReadAsStringAsync();

    return Ok(JsonSerializer.Deserialize<Response>(_privateResponseContent));
}

.Net 7的HTTPClient请求每6分钟响应时间较慢。

.Net 7的HTTPClient请求每6分钟响应时间较慢。

英文:

We are experiencing an issue with HTTP requests where we are seeing that every 6 minutes a HTTP request is taking up to 162ms, on average these requests are taking 7ms. The metrics graph below shows a brief run of a K6 script calling our controller at a rate of 36 requests/minute. Im running K6 locally and both services in question are an AWS ECS instances. The slow response pattern persists for as long as I leave K6 running at this rate. The more you increase the rate at which K6 sends requests the less noticeable the spikes in the requestduration metric. I have metrics around the API controller which I am calling and they are showing an average time taken of 2ms so this is not the issue.

.Net 7的HTTPClient请求每6分钟响应时间较慢。

I initially thought this might be to do with the PooledConnectionIdleTimeout, but the default value for this is 1 minute in .NET 6 and later versions. We are using .Net 7. Not seeing anything on our infrastructure which would cause these spikes either.

My question is has anyone seen similar behaviour making HTTP requests, is it a possible issue with the code below?

We are adding our HTTP Client to our IServiceCollection as follows:

_builder.Services.AddHttpClient&lt;IHttpClient, HttpClient&gt;();

Our HTTP Client is as follows

public class HttpClient : IHttpClient
{
    private readonly Metric.Client.IRecorder c_metrics;
	private readonly System.Net.Http.HttpClient c_httpClient;
	
	public HttpClient(
        Metric.Client.IRecorder metrics,
		System.Net.Http.HttpClient httpClient)
	{
		this.c_httpClient = httpClient;
	}

	public async Task&lt;HttpResponseMessage&gt; GetAsync(
		string requestUrl,
		string correlationId)
	{
		using (var _request = new HttpRequestMessage(HttpMethod.Get, requestUrl))
		{
			_request.Headers.Add(&quot;X-CorrelationId&quot;, correlationId);
            
            using var _timer = this.c_metrics.StartTimer(&quot;requestduration&quot;);
			return await this.c_httpClient.SendAsync(_request);
		}
	}
}

Our controller which we get our HttpClient from our DI container

public Controller(
	IHttpClient httpClient)
{
	this.c_httpClient = httpClient;
}

public async Task&lt;IActionResult&gt; GetAsync(
	[FromQuery] Request request)
{
	var _privateResponse = await this.c_httpClient.GetAsync(_requestUrl, _correlationId);

	if (_privateResponse.StatusCode != HttpStatusCode.OK)
	{
		return StatusCode(500, new Error(Guid.Parse(_correlationId), &quot;Internal server error&quot;));
	}

	var _privateResponseContent = await _privateResponse.Content.ReadAsStringAsync();

	return Ok(JsonSerializer.Deserialize&lt;Response&gt;(_privateResponseContent));
}

答案1

得分: 1

你尝试过设置PooledConnectionIdleTimeout和PooledConnectionLifetime吗?我怀疑你需要修改前者以适应低流量情况。

using var socketHandler = new SocketsHttpHandler()
{
    PooledConnectionIdleTimeout = TimeSpan.FromMinutes(XXX),
    PooledConnectionLifetime = TimeSpan.FromMinutes(YYY),
};

var httpClient = new HttpClient(socketHandler);
英文:

Have you tried setting the PooledConnectionIdleTimeout & PooledConnectionLifetime? I suspect it is the former one you need to modify for low traffic.

using var socketHandler = new SocketsHttpHandler()
{
    PooledConnectionIdleTimeout = TimeSpan.FromMinutes(XXX),
    PooledConnectionLifetime = TimeSpan.FromMinutes(YYY),
};

var httpClient = new HttpClient(socketHandler);

huangapple
  • 本文由 发表于 2023年5月22日 23:09:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76307569.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定