微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何通过Azure函数从Blob存储流式传输二进制文件

如何解决如何通过Azure函数从Blob存储流式传输二进制文件

我正在尝试通过将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");
        }
   }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。