You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure容器应用中ASP.NET Core大文件上传/下载内存占用过高问题求助

大文件流式处理在Azure Container Apps中的内存增长问题

背景

我正在开发一个ASP.NET Core 9 Web API,接收客户端上传的(可能是大体积)文件,将其流式传输到服务器临时文件,处理后把重新打包的文件上传到Blob存储,并将相关元数据发送至数据库。所有服务均部署在Azure中(Azure Container Apps、Azure Blob Storage、Azure SQL DB)。请求的Content-Type: multipart/form-data,仅包含一个文件部分:

Content-Disposition: form-data; name=""; filename="<some_file_name>"

问题现象

容器的内存使用量大致随上传文件的大小增长,最终导致容器内存耗尽(见截图)。原本以为直接流式传输到文件存储只会占用流缓冲所需的内存。

内存随文件上传大小增长

已尝试的解决方案

代码基本遵循ASP.NET Core文件上传文档中的示例,区别在于:1)为简化测试减少了部分校验;2)由于实际代码需将流传递给客户端库进行解压、处理等操作,因此必须处理文件上传流。该代码引发了上述内存问题。

/// <summary>
/// Adds a new Document
/// </summary>
[HttpPost("test", Name = nameof(AddDocumentAsync))]
[DisableFormValueModelBinding]
[DisableRequestSizeLimit]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult> AddDocumentAsync()
{
    if ( !HttpContext.Request.HasFormContentType )
        return BadRequest("No file uploaded.");
    string boundary = HttpContext.Request.GetMultipartBoundary();
    if ( string.IsNullOrEmpty(boundary) )
        return BadRequest("Invalid multipart form-data request.");
    MultipartReader multipartReader = new MultipartReader(boundary, HttpContext.Request.Body);
    MultipartSection? section = await multipartReader.ReadNextSectionAsync();
    if ( section == null )
        return BadRequest("No file found in request body.");
    FileMultipartSection? fileSection = section.AsFileSection();
    if ( fileSection?.FileStream == null )
        return BadRequest("Invalid file.");
    string tempDirectory = Path.GetTempPath();
    string tmpPath = Path.Combine(tempDirectory, Path.GetRandomFileName());
    using ( FileStream fs = new FileStream(tmpPath, FileMode.Create) )
        await fileSection.FileStream.CopyToAsync(fs);
    return Created();
}

观察到/tmp目录下的文件在增长,但内存使用量也以大致相同的速率增长。

如果将目标改为直接将fileSection.FileStream流式传输到Blob存储而非本地文件,则不会出现内存问题。

还尝试使用最小API并通过模型绑定IFormFile。根据文档,默认情况下,文件超过64k时会缓冲到磁盘,这正是我需要的。看到/tmp目录下的文件在增长,但该方案同样导致内存使用量同步增长。

尝试为容器挂载存储卷,怀疑容器因缺少挂载存储卷而使用内存。将Azure Files实例挂载到/blah,并将临时文件的目标路径从/tmp改为/blah。文件正确流式传输到Azure Files存储实例,但内存问题仍然存在。

最后,在Azure Web Services应用中运行上述代码,未观察到内存增长问题;在本地运行应用时,系统或进程内存也未出现Azure Container App中的增长情况。

更新: 根据反馈,还尝试从Blob存储下载文件到容器应用,这同样导致容器内存使用量随下载文件大小增长。使用的代码片段如下:

[HttpGet("test", Name = nameof(TestDocumentAsync))]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> TestDocumentAsync()
{
    string tempDirectory = Path.GetTempPath();
    string tmpPath = Path.Combine(tempDirectory, Path.GetRandomFileName());
    BlobClient blobClient = _blobContainerClient.GetBlobClient("c1f04a61-5ec3-43a8-b7ad-de51ae5185bb.tmp");
    using ( FileStream fs = new FileStream(tmpPath, FileMode.Create) )
        await blobClient.DownloadToAsync(fs);
    return Ok();
}

问题

我认为自己可能误解或误用了某些机制。在Azure Container Apps与ASP.NET环境中,将大体积(1GB至更大)multipart/form-data文件上传到临时存储进行处理并在后续删除的正确方式是什么?或者如何解释即使是简单的Blob存储下载操作也会导致内存增长的现象?

内容的提问来源于stack exchange,提问作者Tyler Southard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:40:56