【发布时间】:2017-12-12 14:17:12
【问题描述】:
我很好奇将密集方法移至 Azure 函数时响应时间会改善多少。 所以我创建了 2 个小应用程序。第一个是 ASP.NET MVC 应用程序(应用服务计划 S1)。第二个是 ASP.NET MVC 应用程序,具有 1 个 Azure Function(在 Function 项目中)、应用服务计划 S1 以及 FunctionApp 的消费计划。
这两个应用程序都是相同的,除了 1 个方法,它被移动到一个 Azure 函数,MergeDocumentsAndExport。
在我的应用程序中,在应用程序启动时会创建给定数量的 Document 记录。
public class Document {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public byte[] Content { get; set; }
public DateTime DateCreated { get; set; }
}
最终用户可以通过单击视图中的按钮下载数据库中的所有Documents。单击此按钮时,将调用方法MergeDocumentsAndExport。
没有 Azure 函数
public byte[] MergeDocumentsAndExport()
{
var startmoment = DateTime.Now;
var baseDocument = new Spire.Doc.Document();
var documents = _documentDataService.GetAllDocuments();
foreach (var document in documents)
{
using (var memoryStream = new MemoryStream(document.Content))
{
var documentToLoad = new Spire.Doc.Document();
documentToLoad.LoadFromStream(memoryStream, FileFormat.Doc);
foreach (Section section in documentToLoad.Sections)
{
baseDocument.Sections.Add(section.Clone());
}
}
}
byte[] byteArrayToReturn;
using (var memoryStream = new MemoryStream())
{
baseDocument.SaveToStream(memoryStream, FileFormat.Doc);
byteArrayToReturn = memoryStream.ToArray();
}
_responseLogger.Log(startmoment, DateTime.Now, nameof(MergeDocumentsAndExport);
return byteArrayToReturn;
}
_responseLogger.Log(..) 方法记录方法的开始和结束,方法名称决定执行时间(也许responselogger 不是该服务的最佳名称)。
使用 Azure 函数
同样的方法被转换成一个 HTTP 触发的 Azure 函数。
[DependencyInjectionConfig(typeof(DependencyConfig))]
public static class MergeDocumentsAndExportFunction
{
[FunctionName("MergeDocumentsAndExportFunction")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "MergeDocumentsAndExport")]HttpRequestMessage req,
TraceWriter log,
[Inject]IDocumentDataService documentDataService,
[Inject]IResponseLogger responseLogger)
{
var startmoment = DateTime.Now;
log.Info("MergeDocumentsAndExportFunction processed a request.");
var baseDocument = new Document();
var documents = documentDataService.GetAllDocuments();
foreach (var document in documents)
{
using (var memoryStream = new MemoryStream(document.Content))
{
var documentToLoad = new Document();
documentToLoad.LoadFromStream(memoryStream, FileFormat.Doc);
foreach (Section section in documentToLoad.Sections)
{
baseDocument.Sections.Add(section.Clone());
}
}
}
using (var memoryStream = new MemoryStream())
{
baseDocument.SaveToStream(memoryStream, FileFormat.Doc);
// Create response to send document as byte[] back.
var response = req.CreateResponse(HttpStatusCode.OK);
var buffer = memoryStream.ToArray();
var contentLength = buffer.Length;
response.Content = new StreamContent(new MemoryStream(buffer));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/ms-word");
response.Content.Headers.ContentLength = contentLength;
responseLogger.Log(startmoment, DateTime.Now, "MergeDocumentsAndExport");
return response;
}
}
在MergeDocumentsAndExportFunction 中添加了一些代码,例如创建和返回HttpResponseMessage。我没有实现异步调用,因为它只是为了这个小测试,我想比较两个环境中方法MergeDocumentsAndExport的同步执行时间。
我得到的结果不是我所期望的。在几乎所有情况下,Azure 函数的执行时间都差不多或更长。我知道 Azure 函数有一个启动时间,我排除了这些时间。也许是因为 Autofac 的依赖注入可能需要一些时间?合并和导出数据库中的 1000 个文档时的结果(以秒为单位):
没有 Azure 功能:
- 49,34
- 50,21
- 51,26
- 49,00
- 50,21
- 50,68
- ...等等... 平均:49.69 秒。
使用 Azure 功能:
- 133,64(启动,排除)
- 77,68
- 85,18
- 66,46
- 86,00
- 65,17
- ...等等... 平均:82.69 秒。
同一方法在不同环境中的执行时间可能会相差 30 秒,将 1000 个文档合并为 1 个。Azure Function 执行时间怎么可能更长(+ 30 秒)?是不是因为我用错了?谢谢。
【问题讨论】:
标签: c# asp.net-mvc azure azure-functions