问题描述
我正在尝试通过将Azure函数与HTTP触发器结合使用,通过Azure API管理从Blob存储中获取二进制文件。应该如何实施Azure功能以达到最小的内存占用?
此实现有效,但似乎需要大量内存,当处理太多并发请求时,会导致内存不足异常:
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function,"get","post",Route = "dbrevisions/{dbRevision}")] HttpRequestMessage request,[Blob("typedatadev/typedata_{dbRevision}.db",FileAccess.Read)] Stream blobStream,string dbRevision,ILogger log)
{
var memoryBlobStream = new MemoryStream();
blobStream.copyTo(memoryBlobStream);
var result = new FileStreamResult(memoryBlobStream,"application/octet-stream");
result.FileStream.Flush();
result.FileStream.Seek(0,SeekOrigin.Begin);
return result;
}
这将最终变为状态502(也没有“冲洗”调用):
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function,ILogger log)
{
var result = new FileStreamResult(blobStream,SeekOrigin.Begin);
return result;
}
这也会失败:
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(blobStream)
};
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
return response;
解决方法
我想像下面那样将内存占用最小化。请注意,不是绑定到流,而是绑定到ICloudBlob
实例(幸运的是,C#函数支持blob input binding的几种风格)并返回开放流。使用内存分析器对其进行了测试,即使对于较大的Blob,也可以正常工作且没有内存泄漏。
注意:您无需寻求流位置0或刷新或处置(处置将在响应端自动完成);
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Storage.Blob;
namespace TestFunction1
{
public static class MyFunction
{
[FunctionName("MyFunction")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous,"get","post",Route = "dbrevisions/{dbRevision}")] HttpRequest req,[Blob("typedatadev/typedata_{dbRevision}.db",FileAccess.Read,Connection = "BlobConnection")] ICloudBlob blob,string dbRevision,ILogger log)
{
var blobStream = await blob.OpenReadAsync().ConfigureAwait(false);
return new FileStreamResult(blobStream,"application/octet-stream");
}
}
}