[英]AuthorizeAttribute not working with Endpoint Routing in ASP.NET Core 3.1
[英]Stream data from an ASP.NET Core 3.1 endpoint without consuming huge amounts of memory
編輯:我有一個診斷中間件組件,可以將響應提取到跟蹤文件中。 那是罪魁禍首。 所以,如果你發現這個是因為你有同樣的問題:檢查你的中間件!
因此,在調用 Web API 端點時,我以流式異步方式從各種數據源收集大量數據(> 100 MB)。 我想以流的方式將該數據轉發給客戶端。
為此,我構建了自己的IActionResultExecutor<T>
來概括這一點,因為我們有一些這樣的端點。
然而,我注意到整個響應在實際發送到客戶端之前被緩存在 memory 中。 不好。 顯然,我做錯了什么,但我無法理解我做錯了什么!
執行器的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);
}
我可以看到整個過程如何在 Visual Studio 中以線性方式分配大量 memory。 我還可以看到 curl 沒有得到任何數據,直到請求完成。 然后一切都在一個 go 中。 具有諷刺意味的是,curl 報告數據的傳輸編碼是chunked
的。 這是一大塊,一些數據流超過 100 MB。 僅僅因為這個原因,我在我的 k8s 集群中買不起強大的 pod,在我看來,這個操作應該生成一堆 Gen 0 對象。 但沒有什么是 GC 不應該處理的。 引用的對象應該以千字節計算!
我嘗試在一些await context.HttpContext.Response.BodyWriter.FlushAsync(cancellationToken)
中撒上一些東西,但似乎沒有任何區別。
我究竟做錯了什么?
問題已解決:我在管道中有一些調試日志中間件,它打開了緩沖以跟蹤發送給客戶端的響應。 哦!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.