Azure Function App使用FileStreamResult下载超1GB文件中断问题
问题分析与解决方案
核心原因:Azure Function执行超时限制
你的问题本质是消费计划下的Azure Function超时限制导致的:消费计划的函数默认最大执行时长为10分钟,1GB文件下载耗时9分钟刚好卡在阈值边缘,更大文件的下载时间超过10分钟后,Azure会强制终止函数进程,主动发送FIN包断开连接,且不会抛出显性错误。
解决方案
1. 切换函数宿主计划(最直接的解决路径)
若需支持超过10分钟的下载任务,将消费计划更换为高级计划(Premium Plan)或专用计划(Dedicated Plan):
- 这两类计划允许将函数执行超时最长设置为60分钟,需在
host.json中配置:
{ "functionTimeout": "01:00:00" }
2. 重构下载逻辑,规避函数中转压力
不要让函数作为中转流式返回Blob,改为生成Blob的SAS URL返回给客户端,让客户端直接从Azure Storage下载:
[FunctionName("GeoDocsGet")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ExecutionContext context, ILogger log) { try { string fileKey = req.Query["filekey"]; var config = new ConfigurationBuilder() .SetBasePath(context.FunctionAppDirectory) .AddEnvironmentVariables() .Build(); var dbConnStr = config.GetConnectionString("sqldb_connection"); // 省略数据库查询、变量赋值逻辑 var blobClient = new BlobServiceClient(storageConnString); var destStorageContainer = blobClient.GetBlobContainerClient(containerName); var blockBlob = destStorageContainer.GetBlobClient(fileName); // 生成有效期1小时的SAS访问URL var sasBuilder = new BlobSasBuilder() { BlobContainerName = containerName, BlobName = fileName, ExpiresOn = DateTimeOffset.UtcNow.AddHours(1), Protocol = SasProtocol.Https }; sasBuilder.SetPermissions(BlobSasPermissions.Read); var sasUri = blockBlob.GenerateSasUri(sasBuilder); // 重定向到SAS URL,客户端直接发起下载 return new RedirectResult(sasUri.ToString(), permanent: false); } catch (Exception ex) { log.LogError(ex.Message, ex); throw; } }
这种方式的优势:
- 函数执行时长极短,完全避开超时限制
- 下载流量直接从Storage流向客户端,降低函数资源消耗与成本
3. 调整App Service请求超时(适配高级/专用计划)
在Azure门户的Function App配置页,进入设置->常规设置,调整「请求超时」值(专用计划最长可设为900秒,需与函数超时配置匹配)。
额外排查方向
- 直接通过Storage Explorer测试Blob下载,排除Blob本身损坏的可能
- 确认客户端网络无防火墙/代理中断长连接(内外网测试结果一致,此因素概率极低)
内容的提问来源于stack exchange,提问作者pauls
相关产品推荐
相关产品推荐

