Azure函数从Azurite获取Blob图片失败求助
问题:Azure函数读取Azurite Blob时出现500错误,卡顿25秒
函数代码
[FunctionName("GetImage")] public static IActionResult GetImage( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "image/{fileName}")] HttpRequest req, [Blob("images/{fileName}", FileAccess.Read, Connection = "BlobConnection")] Stream blob, ILogger log, string fileName) { log.LogInformation("Get file from blob " + fileName + " length: " + blob.Length); MemoryStream ms = new MemoryStream(); blob.CopyTo(ms); return new FileContentResult(ms.ToArray(), "image/jpeg"); }
问题现象
- 初始问题:函数无法启动,报内部500错误,关联Blob存储;添加配置项
"AzureWebJobsSecretStorageType": "files"后启动恢复正常 - 执行异常:
- 日志能正常记录目标文件名和文件大小
- 在
blob.CopyTo(ms)代码处卡顿约25秒 - 最终抛出500内部服务器错误,错误根源为
Azure.Storage.Blobs.BlobRestClient.Download
环境信息
- Azure Functions Core Tools版本:4.0.4915
- 函数运行时版本:4.14.0.19631
- Azurite-Blob版本:3.20.1
完整异常堆栈
Executed 'GetImage' (Failed, Duration=26013ms) System.Private.CoreLib: Exception while executing function: GetImage. Azure.Storage.Blobs: Service request failed. Status: 500 (Internal Server Error) Inner source of Exception: Azure.Storage.Blobs.BlobRestClient.Download(... Azure.RequestFailedException: Service request failed. Status: 500 (Internal Server Error) Headers: Server: Azurite-Blob/3.20.1 x-ms-creation-time: Wed, 30 Nov 2022 12:55:17 GMT ETag: "0x1D64FE85292CAC0" x-ms-blob-type: BlockBlob x-ms-lease-state: available x-ms-lease-status: unlocked x-ms-client-request-id: 6e6dff50-8c8b-4ccd-bb76-e9b460008293 x-ms-request-id: 91976feb-4421-47a3-9a0e-16a26dc6ad70 x-ms-version: 2021-10-04 Accept-Ranges: bytes Date: Thu, 15 Dec 2022 08:46:32 GMT x-ms-server-encrypted: true x-ms-blob-content-md5: 3KQmtVIakH8iR9D9PlFbSg== Connection: keep-alive Keep-Alive: REDACTED Last-Modified: Wed, 30 Nov 2022 12:55:17 GMT Content-Length: 18304 Content-Type: image/jpeg Content-Range: bytes 0-18303/18304 Content-MD5: 3KQmtVIakH8iR9D9PlFbSg== Content-Disposition: at Azure.Storage.Blobs.BlobRestClient.Download(String snapshot, String versionId, Nullable`1 timeout, String range, String leaseId, Nullable`1 rangeGetContentMD5, Nullable`1 rangeGetContentCRC64, String encryptionKey, String encryptionKeySha256, Nullable`1 encryptionAlgorithm, Nullable`1 ifModifiedSince, Nullable`1 ifUnmodifiedSince, String ifMatch, String ifNoneMatch, String ifTags, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.StartDownloadAsync(HttpRange range, BlobRequestConditions conditions, Boolean rangeGetContentHash, Int64 startOffset, Boolean async, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.DownloadStreamingInternal(HttpRange range, BlobRequestConditions conditions, Boolean rangeGetContentHash, IProgress`1 progressHandler, String operationName, Boolean async, CancellationToken cancellationToken) at Azure.Storage.Blobs.Specialized.BlobBaseClient.<>c__DisplayClass92_0.<b__0>d.MoveNext() --- End of stack trace from previous location --- at Azure.Storage.LazyLoadingReadOnlyStream`1.DownloadInternal(Boolean async, CancellationToken cancellationToken) at Azure.Storage.LazyLoadingReadOnlyStream`1.ReadInternal(Byte[] buffer, Int32 offset, Int32 count, Boolean async, CancellationToken cancellationToken) at Azure.Core.Pipeline.TaskExtensions.EnsureCompleted[T](Task`1 task) at Azure.Storage.LazyLoadingReadOnlyStream`1.Read(Byte[] buffer, Int32 offset, Int32 count) at System.IO.Stream.CopyTo(Stream destination, Int32 bufferSize) at System.IO.Stream.CopyTo(Stream destination) at StandardFunctions.BloobFunctions.GetImage(HttpRequest req, Stream blob, ILogger log, String fileName) in C:\Dev\StandardFunctions\BloobFunctions.cs:line 39
解决思路
1. 排查版本兼容性
- 升级Azurite到最新稳定版本,或回退到与Azure Functions Runtime 4.14.0匹配的版本(如3.19.x系列),消除版本不匹配导致的API调用异常
- 检查项目中
Azure.Storage.BlobsSDK版本,确保其与Azurite版本兼容
2. 优化Blob读取逻辑
- 放弃Blob绑定自动获取
Stream的方式,改为手动创建Blob客户端,增加超时和重试控制,同时避免内存流复制:[FunctionName("GetImage")] public static async Task<IActionResult> GetImage( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "image/{fileName}")] HttpRequest req, ILogger log, string fileName) { var connectionString = Environment.GetEnvironmentVariable("BlobConnection"); var blobServiceClient = new BlobServiceClient(connectionString); var containerClient = blobServiceClient.GetBlobContainerClient("images"); var blobClient = containerClient.GetBlobClient(fileName); try { var downloadOptions = new BlobDownloadOptions { Timeout = TimeSpan.FromSeconds(10), Retry = new Azure.Core.RetryOptions { MaxRetries = 2 } }; var response = await blobClient.DownloadAsync(downloadOptions); log.LogInformation($"Get file from blob {fileName} length: {response.Value.ContentLength}"); return new FileStreamResult(response.Value.Content, "image/jpeg"); } catch (RequestFailedException ex) { log.LogError(ex, $"Failed to download blob {fileName}"); return new StatusCodeResult((int)ex.Status); } }
3. 重置Azurite存储
- 关闭Azurite服务,删除本地
.azurite存储目录,重新初始化存储,排除存储文件损坏导致的错误
4. 调整函数配置
- 尝试移除
"AzureWebJobsSecretStorageType": "files"配置,恢复默认秘密存储方式,排查该配置是否影响Blob绑定的底层行为 - 在
host.json中增加函数超时时间:{ "functionTimeout": "00:05:00" }
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

