ASP.NET Core MVC 响应缓慢生成

ASP.NET Core MVC Slow response generation

提问人:Hentov 提问时间:7/22/2018 最后编辑:Hentov 更新时间:9/18/2023 访问量:4996

问:

我有一个 ASP.NET Core MVC Web应用程序,它有一个端点,它以json的形式返回一些数据。最主要的问题是,我的数据大约是 5 MB 的原始(非缩进)JSON,并且响应需要很长时间。

我设置了一些指标,发现平均而言,我的应用程序执行的处理大约需要 30 毫秒。然而,整个响应在超过 250 毫秒后返回。

我正在使用计算机上运行的应用程序的本地实例进行测试,并使用 postman 发送 get 请求,因此网络延迟最小。

这是我的控制器的样子

    [HttpGet("getData")]
    public IActionResult GetData()
    {
        Stopwatch sw = Stopwatch.StartNew();
        long a, b, c;

        var data = this._cacheInternal.GetValidDataSet();
        a = sw.ElapsedMilliseconds;

        sw.Restart();
        var processedData = this.ProcessData(data, false);
        b = sw.ElapsedMilliseconds;

        sw.Restart();
        var serialized = JsonConvert.SerializeObject(processedData);
        c = sw.ElapsedMilliseconds;

        this._log.Info($"Data: {a} ms. Processing {b} ms. Serialization {c} ms.");

        return this.Ok(serialized);
    }

这是我在检查 AspNetCore 日志时发现的内容。

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/api/status/getData
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Route matched with {action = "GetData", controller = "Status"}. Executing action DemoApp.Controllers.StatusController.GetData (DemoApp)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method DemoApp.Controllers.StatusController.GetData (DemoApp) - Validation state: Valid
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action method DemoApp.Controllers.StatusController.GetData (DemoApp), returned result Microsoft.AspNetCore.Mvc.OkObjectResult in 31.4532ms.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
      Executing ObjectResult, writing value of type 'System.String'.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action DemoApp.Controllers.StatusController.GetData (DemoApp) in 69.2546ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 175.2726ms 200 text/plain; charset=utf-8

此请求的秒表日志记录如下:

Data: 1 ms. Processing 19 ms. Serialization 10 ms.

正如您从我的控制器的日志中看到的那样:

。返回结果 Microsoft.AspNetCore.Mvc.OkObjectResult 在 31.4532 毫秒内
这与我的秒表指标相匹配,并且是应用程序实际执行我的代码的时间量。

从那里开始,ASP接管了另外两点:

在 69.2546 毫秒内执行操作 DemoApp.Controllers.StatusController.GetData (DemoApp)

请求在 175.2726ms 200 文本/纯文本中完成;字符集=utf-8

所以我的问题是,在 ASP 获取我传递给的结果后,我怎样才能找出这两个时间点发生了什么,这需要很多时间(并修复它)this.Ok()

同样,我返回的响应非常大(对于此示例,1.2MB 原始 JSON)。但我不明白是什么导致了这么长的延迟(鉴于我所做的序列化只需要 10 毫秒)

我正在使用 ASP.NET Core MVC 并以 .NET Core 2.1 为目标。该应用程序由 Kestrel 托管。

C# asp.net HTTP Web 应用程序 ASP.net-core-mvc

评论

0赞 Crowcoder 7/22/2018
我会称 250 毫秒为 5 MB 数据的胜利。你在寻找什么样的时间?你试过gzip压缩吗?
1赞 Crowcoder 7/22/2018
由于您在 Core 上,您还可以通过完全绕过控制器来加快速度。然后,您可以进行一个委托,该委托跳过控制器管道并返回数据本身,但这可能不合适,尤其是在您需要授权等 MVC 内容时。mapuse
0赞 Hentov 7/22/2018
这 250 毫秒是 1.2MB,我不得不仔细检查结果。我对这些数字没问题,但是当数据变得非常大(30MB)时,需要一分钟多的时间,这有点问题。我主要担心的是我的代码设法在 10 毫秒内序列化数据 (Newtonsoft),然后 ASP 在 220+ 毫秒内做一些其他事情。我想知道它为什么这么慢。至于 gzip - 不,我没有尝试过
0赞 Ben Adams 7/22/2018
250 毫秒内 1.2MB => 4.8MB/s => 38.4MBit/s => ~40MBit/s(TCP/IP/HTTP 开销)。客户端和服务器之间的延迟和带宽是多少?
1赞 videokojot 6/23/2020
我们看到了同样的问题。当响应约为 1MB 时,操作执行和整个请求时间的差异为 cca 250ms。当响应增长时,时间也会线性增长(30MB 响应最多 15 秒)。您是否@Hentov找到原因/解决方案,或者至少知道如何诊断它的来源?

答: 暂无答案