繁体   English   中英

如何通过Azure功能上传大文件?

[英]How to upload a large file through an Azure function?

我正在探索Azure功能。 到目前为止我测试过的场景效果很好。

我正试图找出一种通过Azure功能上传文件(20MB +)的方法。

我们的想法是,Azure功能将首先验证经过身份验证的用户是否可以在保留请求的流并将其保存到BLOB存储之前上载文件。

以下是客户端的代码,它创建一个StreamContent来将字节传输到服务器:

using (Stream fileStream = ...)
{
    var streamContent = new StreamContent(fileStream);

    streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    streamContent.Headers.ContentLength = fileStream.Length;
    streamContent.Headers.Add("FileId", fileId);

    var responseMessage = await m_httpClient.PutAsync(<validURI>, streamContent);

    responseMessage.EnsureSuccessStatusCode();

    succeeded = true;
}

这是服务器端的代码。

[FunctionName("upload-data")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "put")]HttpRequestMessage req, TraceWriter log)
{
    try
    {
         //  Initialize stuff.

         //  Validate authenticated user & privileges.  

         //  Get the content stream of the request and 
         //  save it in the BLOB storage.

         return req.CreateResponse(HttpStatusCode.OK);
    }
    catch (Exception exc)
    {
        return req.CreateResponse(HttpStatusCode.InternalServerError, exc);
    }
}

我在方法的开头放了一个断点。 无论文件有多大,我都希望在客户端发送请求后立即点击断点。 但事实并非如此。

我猜测Azure函数在调用方法之前试图获取请求主体的所有内容。 我还认为我发送的文件可能超过了底层Web作业的4 MB限制,但我没有看到配置它的方法。

是否可以通过流式传输将大文件上传到Azure功能? 有没有办法让这项工作?

我找到了另一种做事方式。 这是适合我的解决方案。

当客户端需要上传文件时,它会调用Azure功能进行身份验证(使用框架提供的身份)并授权(它可以是表存储中的简单有针对性的检查,这意味着他允许执行这样的操作)。

Azure功能将要求共享访问签名来访问特定Blob。 SAS将允许客户端在限定时间内以只写权限访问Blob存储(注意Azure上的时钟偏差)。

然后,客户端将使用返回的SAS将文件直接上载到Blob存储。 这样,它避免了Afzaal Ahmad Zeeshan提到的与客户端的长期通信,并且由于Azure功能不再依赖于客户端的连接速度,因此降低了总体成本。

你跟随一个不好的做法,Kzrystof。 Azure功能不适用于与客户端设备的长期通信。 我不确定,为什么有人可能有兴趣指导您编写一个程序来管理Azure功能并强制它执行它不打算做的事情。

大型,长时间运行的功能可能会导致意外的超时问题。

现在想象一下,你可能有一个良好的互联网连接,但用户可能不是。 还有其他一些问题,你必须先注意一下。 这是官方文档的摘录, https://docs.microsoft.com/en-us/azure/azure-functions/functions-best-practices

如果我必须设计此应用程序,我将使用App Service→Azure Storage→Azure Functions。 这将是我的应用程序架构的工作流程。

在设计方法中,我的应用程序会轮流处理这些信息,例如App Service可以处理图像上传,在那里我可以指定用户是否可以上传。 可以使用ASP.NET Core或任何其他语言或框架来开发Web应用程序的那一面,并且您知道可以轻松升级它以支持最多20MB的文件上载。

我为什么要求你扭曲设计? 你有一个Blob函数,我建议使用Blob函数,因为,

如果可能,函数应该是无状态的和幂等的。 将任何所需的状态信息与您的数据相关联。 例如,正在处理的订单可能具有关联的州成员。 函数可以基于该状态处理订单,而函数本身保持无状态。

该功能本身是无状态的,这意味着它们一定不能保留任何东西的任何信息和解决,这将需要你有其他的中间件(或frontware)与身份的服务器进行通信,这就是为什么我建议使用应用服务这里因为它可以包含验证用户的必要信息,然后Blob和&rarr finally函数, 如果需要的话

然后,一旦它离开那里,进入Azure存储,然后我就可以拥有WebHooks,或者直接Blob存储触发器从那里处理委托并处理Azure功能中的图像 - 如果需要功能了。 看一下Blob存储触发器如何用于启动各种用途的函数, https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-storage-blob-triggered-功能

设置ContentLength标头后,您将不再对其进行流式传输。 您需要使用PushStreamContent类并以块的形式写入流。

您是否仍然能够以服务器端访问该流作为块,我不知道。 Azure函数管道中的某些内容可能会在将流提供给函数之前缓冲流。

另一种解决方案(可能不是最佳实践)是使用块来发布文件。 但是它需要你跟踪这些块并在之后合并它们。

例如:

  • 前端 - 向端点发送多个块(多个POST)
  • 后端 - 存储块
  • 前端 - 发送完成后,使用端点确认
  • 后端 - 合并块

Dropzone JS - Chunking

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM