使用Always On与ASP.NET Core Web API相同时,Azure Function对首次HTTPS调用的响应速度很慢 具有Azure功能:或使用ASP.NET Web应用程序API:

问题描述

需要帮助来理解为什么第一个请求总是比其他请求花费更长的时间。测试案例:通过POST请求发送二进制数据。

这是Azure Application Insights中的典型图片,在同一分钟内触发了2个系列的4个请求:

Request Duration

服务器端

只需将二进制数据读入字节数组。

具有Azure功能:

    [FunctionName("TestSpeed")]
    public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous,"get","post",Route = "TestSpeed")]HttpRequestMessage req,Binder binder,ILogger log)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        byte[] binaryData = req.Content.ReadAsByteArrayAsync().Result;

        sw.Stop();
        
        return req.CreateResponse(HttpStatusCode.OK,$"Received {binaryData.Length} bytes. Data Read in: {sw.ElapsedMilliseconds} ms");
    }

或使用ASP.NET Web应用程序API:

public class MyController : ControllerBase
{
    private readonly ILogger<MyController> _logger;

    public MyController(ILogger<MyController> logger)
    {
        _logger = logger;
    }

    [HttpPost]
    public IActionResult PostBinary()
    {
        _logger.LogInformation(" - TestSpeed");
        var sw = new Stopwatch();
        sw.Start();

        var body = Request.Body.ToByteArray();

        sw.Stop();
        return Ok($"Received {body.Length} bytes. Data Read in: {sw.ElapsedMilliseconds} ms");
    }
}

客户端(仅用于测试)

使用.NET Framework,C#控制台应用程序...

    private static void TestSpeed()
    {
        Console.WriteLine($"- Test Speed - ");

        string requestUrl = "https://*******.azurewebsites.net/api/TestSpeed";

        string path = "/Users/temp/Downloads/1mb.zip";

        byte[] fileToSend = File.ReadAllBytes(path);

        var sw = new Stopwatch();
        for (int i = 0; i < 4; i++)
        {
            sw.Reset();
            sw.Start();
            var response = SendFile(fileToSend,requestUrl);
            sw.Stop();
            Console.WriteLine($"{i}: {sw.ElapsedMilliseconds} ms. {response}");
        }
    }

    private static string SendFile(byte[] bytesToSend,string requestUrl)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);
        request.Method = "POST";
        request.ContentType = "application/octet-stream";
        request.ContentLength = bytesToSend.Length;

        using (Stream requestStream = request.GetRequestStream())
        {
            // Send the file as body request. 
            requestStream.Write(bytesToSend,bytesToSend.Length);
            requestStream.Close();
        }

        try
        {
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (var sr = new StreamReader(response.GetResponseStream()))
                {
                    var responseString = sr.ReadToEnd();
                    return responseString;
                }
            }
        }
        catch (Exception e)
        {
            return "ERROR:" + e.Message;
        }
    }

我尝试过的嫌疑人:

  • 这不是冷启动/热身的事情,因为该行为在同一分钟内重复出现。.并且我也启用了“始终开启”。
  • 比较HTTP和HTTPS-相同的行为。
  • Azure函数与ASP.NET核心Web API应用程序-相同的行为。我注意到的唯一区别是使用函数,在调用之前,请求内容已在服务器端完全接收:

ASP.NET web API: 5512 ms. Received 1044397 bytes. Data Read in: 3701 ms
Function App: 5674 ms. Received 1044397 bytes. Data Read in: 36 ms

  • 发送1Kb与1Mb-行为相同,首次通话需要花费更多。
  • 在Localhost上运行服务器-行为类似,但与远程服务器相比,差异要小得多! (看起来网络距离很重要……)

有一些会话创建开销吗?如果是这样,为什么这么大? 我能做些什么?

解决方法

由于您的测试界面位于Web程序中,因此即使您打开常开开关,该程序发生了什么或该程序是否可以保持活动状态,您也需要举一张支持票以与官员确认。从开发人员的角度来看,建议您像这样进行测试:

  1. 重新部署Web界面后,首先使用功能应用进行测试,然后使用webapi界面进行测试以比较测试时间。

  2. 再次重新部署,首先使用webapi进行测试,然后使用function app进行测试。比较测试时间。

  3. 不需要部署。在第二次测试的基础上,5分钟后再次测试。使用功能app或webapi的顺序无关紧要。查看测试时间数据。

我认为问题应该在IIS上。 IIS本身具有回收机制。该应用程序将长时间不使用,或在部署后会有延迟。建议与官员确认。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...