【问题标题】:http2 request docker container memory goes up and up - doesn't releasehttp2 请求 docker 容器内存不断增加 - 不释放
【发布时间】:2020-07-23 15:10:51
【问题描述】:

我在 Linux 上的 docker 容器中有 .NET Core 3.1 Web API。

我使用测试工具向 Web API 发出 1000 个连续请求。

Web API 控制器如下所示:

    public MyController(ISendService sservice)
    {
        _sservice = sservice;
    }


    [HttpPost()]
    public async Task<IActionResult>  SendMessage([FromBody] SendMessageRequest request)
    {
            await _sservice.SendIt(request.Message);
    }

我的发送服务如下所示:

    public class SendService: ISendService
    {
       private readonly HttpClient _client;

       public SendService(HttpClient client)
       {
           _client = client;
       }

       public async Task SendMessage(string data)
       {
          var request= new HttpRequestMessage(HttpMethod.Post, "https://somelocation/test") { Version = new Version(2, 0) };

          request.Content = new StringContent(data);

          var response = await _client.SendAsync(request);
           
         //Log response
       }
    }

我在 Startup 中添加 SendService,如下所示:

        services.AddHttpClient<ISendService, SendService>().ConfigurePrimaryHttpMessageHandler(() =>
        {
            var handler = new HttpClientHandler { SslProtocols = SslProtocols.Tls12 };
            var store = new Store.GetStore();
            handler.ClientCertificates.Add(store.certificate);
            return handler;
        });

我的问题是,每当调用 SendMessage 时,docker 容器内的内存使用量都会随着每个请求而上升。即我调用它 10 次,内存会上升并停留在那里。我调用它 1000 次,内存不断增加,超过 85%(读取到 .NET Core 3.1 中的限制应该是 75%),并且在每个测试场景中等待 20 分钟。

为什么它似乎没有进行垃圾收集或释放内存?我正在运行测试,但我认为它将达到 100%,并且服务将停止,这不好。谢谢

【问题讨论】:

  • 连接可能没有关闭。从 cmd.exe >Netstat -A 试试看你是否有多个连接。

标签: c# docker asp.net-core docker-compose httpclient


【解决方案1】:

现在,您正在阻止对您的服务的每次调用

_client.SendAsync(request).GetAwaiter().GetResult()

这是一个很大的禁忌。 你可以在这里阅读更多信息:https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

更改您的 ISendService 接口
void SendMessage(string data)

Task SendMessage(string data)

然后在您的 SendService 中,在方法声明中添加 async 并替换以下行

var response = _client.SendAsync(request).GetAwaiter().GetResult();

var response = await _client.SendAsync(request);

然后在您的控制器中添加 async 关键字并像这样等待它:

[HttpPost()]
public async Task<IActionResult> SendMessage([FromBody] SendMessageRequest request)
{
        await _sservice.SendIt(request.Message);
}

另外,关于内存使用,您确定这是个问题吗?未使用的内存毫无价值... :)

【讨论】:

  • 非常感谢您的宝贵时间。我按照您的建议进行了尝试,并且正在运行另一个测试(请参阅上面的更新问题)。不幸的是,初始测试(docker 容器限制为 40M 内存)显示了相同的结果。我正在尝试使用 60M。
  • 您可以在此处找到有关内存使用的更多信息:stackoverflow.com/questions/57591344/…
  • 请注意,我不建议接受该问题的答案。我只是尝试增加 ram 的数量,然后让 dotnet 处理 GC :)
  • 当然未使用的内存一文不值,这正是它的问题。 GC 不会收集所有内容,特别是具有有效(静态或全局)引用且未被代码处置/处理的对象。类型化客户端作为临时服务添加,但在后台重用 HttpMessageHandler。也许创建一个新的处理程序会导致内存问题。
猜你喜欢
  • 1970-01-01
  • 2013-10-05
  • 2018-12-25
  • 2013-07-02
  • 2019-10-25
  • 2022-08-17
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
相关资源
最近更新 更多