简体   繁体   English

来自 ASP.NET 核心 3.1 端点的 Stream 数据,无需消耗大量 memory

[英]Stream data from an ASP.NET Core 3.1 endpoint without consuming huge amounts of memory

Edit: I had a diagnostics middleware component that pulled out responses into a trace file.编辑:我有一个诊断中间件组件,可以将响应提取到跟踪文件中。 That was the culprit.那是罪魁祸首。 So, if you find this because you have the same problem I had: check your middleware!所以,如果你发现这个是因为你有同样的问题:检查你的中间件!

So at the call of a Web API endpoint, I'm gathering huge amounts of data (> 100 MB) from various data sources in a streaming asynchronous fashion.因此,在调用 Web API 端点时,我以流式异步方式从各种数据源收集大量数据(> 100 MB)。 I want to forward that data to the client in a streaming fashion.我想以流的方式将该数据转发给客户端。

For this purpose I have built my own IActionResultExecutor<T> to generalize this as we have a few of these endpoints.为此,我构建了自己的IActionResultExecutor<T>来概括这一点,因为我们有一些这样的端点。

I have however noticed that the entire response is cached in memory before it's actually sent to the client.然而,我注意到整个响应在实际发送到客户端之前被缓存在 memory 中。 Not good.不好。 Obviously, I'm doing something wrong, but I cannot understand what I'm doing wrong!显然,我做错了什么,但我无法理解我做错了什么!

The executor's ExecuteAsync looks like this:执行器的ExecuteAsync如下所示:

public async Task ExecuteAsync(ActionContext context, AsyncStreamResult result)
{
   var bufferingFeature = context.HttpContext.Features.Get<IHttpResponseBodyFeature>();
   if (bufferingFeature != null)
      bufferingFeature.DisableBuffering();

   context.HttpContext.Response.StatusCode = StatusCodes.Status200OK;
   context.HttpContext.Response.ContentType = "application/json; charset=utf-8";

   var cancellationToken = context.HttpContext.RequestAborted;
   await context.HttpContext.Response.StartAsync(cancellationToken);
   await context.HttpContext.Response.WriteAsync("[", cancellationToken);
   bool seenFirstItem = false;

   await foreach (var item in result.Data) {
      if (seenFirstItem)
         await context.HttpContext.Response.WriteAsync(",", cancellationToken);

      await context.HttpContext.Response.BodyWriter.WriteAsync(item.JsonBytes, cancellationToken);

      seenFirstItem = true;
   }

   await context.HttpContext.Response.WriteAsync("]", cancellationToken);
}

I can see how the entire process allocates a lot of memory in a linear fashion in Visual Studio.我可以看到整个过程如何在 Visual Studio 中以线性方式分配大量 memory。 I can also see curl not getting any data, until the request is finished.我还可以看到 curl 没有得到任何数据,直到请求完成。 Then everything comes in one go.然后一切都在一个 go 中。 The irony is that curl reports that the data's transfer encoding is chunked .具有讽刺意味的是,curl 报告数据的传输编码是chunked的。 That's one big chunk, Some of the data streams are in excess of 100 MB.这是一大块,一些数据流超过 100 MB。 and I can't afford beefy pods in my k8s cluster for that reason alone, The way I see it, this operation should generate a bunch of Gen 0 objects.仅仅因为这个原因,我在我的 k8s 集群中买不起强大的 pod,在我看来,这个操作应该生成一堆 Gen 0 对象。 but nothing that the GC shouldn't be able to handle.但没有什么是 GC 不应该处理的。 Referenced objects should be counted in kilobytes!引用的对象应该以千字节计算!

I've tried sprinkle in some await context.HttpContext.Response.BodyWriter.FlushAsync(cancellationToken) , but nothing appears to make any difference.我尝试在一些await context.HttpContext.Response.BodyWriter.FlushAsync(cancellationToken)中撒上一些东西,但似乎没有任何区别。

What am I doing wrong?我究竟做错了什么?

Problem solved: I had some debug logging middleware in the pipeline that turned on buffering to trace responses sent to clients.问题已解决:我在管道中有一些调试日志中间件,它打开了缓冲以跟踪发送给客户端的响应。 DOH!哦!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AuthorizeAttribute 不适用于 ASP.NET Core 3.1 中的端点路由 - AuthorizeAttribute not working with Endpoint Routing in ASP.NET Core 3.1 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用 - AuthorizeAttribute with Roles not working when migrating from MVC to Endpoint Routing in ASP.NET Core 3.1 无法访问 ASP.NET Core 3.1 Web API Z9BBF373797BF7CF7BA6ZC8002 中的端点,5 - Unable to access an endpoint in ASP.NET Core 3.1 Web API Controller, from View 需要帮助分析ASP.Net Core 3.1 memory dump - Need help analyzing ASP.Net Core 3.1 memory dump 显示评论而不刷新视图 Asp.Net Core 3.1? - Display comment without refreshing the view Asp.Net Core 3.1? 使用 OWIN 从 asp.net 核心发布的 oAuth 承载 - consuming oAuth bearer issued by OWIN from asp.net core ASP.NET Web API (.NET Core 3.1) 中的端点路由问题 - Problem with endpoint routing in ASP.NET Web API (.NET Core 3.1) Asp.Net从视图向控制器发送大量数据 - Asp.Net Sending large amounts of data from view to controller 如何在 ASP.NET Core 3.1 中访问 IAuthorizationHandler 中的会话数据? - How to access session data in IAuthorizationHandler in ASP.NET Core 3.1? Asp.Net Core 3.1 数据被检索但未保存到数据库中 - Asp.Net Core 3.1 Data is retrieved but not saved into database
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM