ASP.NET WebAPI 和 IIS 中的请求时间不一致

Posted

技术标签:

【中文标题】ASP.NET WebAPI 和 IIS 中的请求时间不一致【英文标题】:Inconsistent request timings in ASP.NET WebAPI and IIS 【发布时间】:2015-06-27 09:11:33 【问题描述】:

问题

我正在测试我们的一个 AngularJS + ASP.NET WebAPI 应用程序的性能。我观察到的奇怪之处在于,完全相同的查询在 Fiddler 中以不同的时间执行

这种行为不仅在服务器上观察到,在我的本地机器上也观察到。

详情

该应用程序使用 Chrome 进行测试,并使用 ASP.NET WebAPI (Microsoft.AspNet.WebApi version 5.2.2) 和 Angular JS version 1.3.8 编写。

服务器是带有 SQL Server 2008 和 IIS 7.5 的 Windows Server 2008 R2。

我的本​​地计算机是装有 Visual Studio 2013 和 SQL Server 2014 的 Windows 8.1。

我注意到,根据 Fiddler,完全相同的查询以不同的时间执行(蓝色的查询是相同的,白色的查询是另一种完全相同的查询):

例如26号查询的详细时序为:

Request Count:   1
Bytes Sent:      583        (headers:517; body:66)
Bytes Received:  3,844      (headers:260; body:3,584)

ACTUAL PERFORMANCE
--------------
ClientConnected:    17:26:25.099
ClientBeginRequest: 17:27:26.544
GotRequestHeaders:  17:27:26.544
ClientDoneRequest:  17:27:26.544
Determine Gateway:  0ms
DNS Lookup:         0ms
TCP/IP Connect: 0ms
HTTPS Handshake:    0ms
ServerConnected:    17:26:25.102
FiddlerBeginRequest:    17:27:26.544
ServerGotRequest:   17:27:26.544
ServerBeginResponse:    17:27:26.554
GotResponseHeaders: 17:27:26.554
ServerDoneResponse: 17:27:26.554
ClientBeginResponse:    17:27:26.554
ClientDoneResponse: 17:27:26.554

    Overall Elapsed:    0:00:00.010

28号查询的详细时序为:

Request Count:   1
Bytes Sent:      583        (headers:517; body:66)
Bytes Received:  3,844      (headers:260; body:3,584)

ACTUAL PERFORMANCE
--------------
ClientConnected:    17:26:25.099
ClientBeginRequest: 17:27:29.104
GotRequestHeaders:  17:27:29.104
ClientDoneRequest:  17:27:29.104
Determine Gateway:  0ms
DNS Lookup:         0ms
TCP/IP Connect: 0ms
HTTPS Handshake:    0ms
ServerConnected:    17:26:25.102
FiddlerBeginRequest:    17:27:29.104
ServerGotRequest:   17:27:29.104
ServerBeginResponse:    17:27:29.616
GotResponseHeaders: 17:27:29.616
ServerDoneResponse: 17:27:29.616
ClientBeginResponse:    17:27:29.616
ClientDoneResponse: 17:27:29.616

    Overall Elapsed:    0:00:00.512

正如我所说,它们是完全相同的查询(相同的标题、相同的数据等)。

查询 28 在查询 26 之后 1-2 秒执行。

问题

这种行为的主要原因是什么?我应该在哪里搜索问题?奇怪的是,查询先快后慢,然后又快了,等等。我没有理由认为问题与数据缓存有关.

如何精确测试服务器上的计时以找出0.0100.512秒之间的这种差异?差异超过50倍。

【问题讨论】:

你在使用异步方法吗? 不,我不使用async :) 尝试使您的操作异步。这有什么不同吗? 我想知道您是否在 IIS 或您的数据库中遇到了连接池问题。如果您的请求以某种方式间隔开,您可能会导致请求排队,这意味着第一个请求会出现得很快,而随后的请求会更慢(因为他们必须等待前一个请求完成)。如果增加数据库的连接池大小会发生什么?如果您在每个请求之间造成 10 秒的人为延迟,会发生什么情况? 我想有几个问题:您的数据库是否处于任何负载下?来自其他应用程序/其他请求?这是目前唯一提出的请求吗? 【参考方案1】:

好吧,如果您能与我们分享正在服务器上执行的代码,以及奇数和偶数请求之间的区别,那将非常有帮助。

我在这里做了很多假设,所以请原谅任何愚蠢的错误。

我以前见过这种行为,在那种情况下,它与 SqlServer 的执行计划缓存有关。

您可以在 Internet 上找到大量有关此的信息,简而言之,在执行查询之前,SqlServer 的引擎会进行一些计算并决定为该查询检索数据的最佳方式是什么。这给您的查询时间增加了额外的负担,SqlServer 知道这一点并缓存该执行计划,以便以后可以重用。

我不知道有关它的所有详细信息,但如果我不得不猜测,我会说某些东西使该缓存无效,因此需要每隔一段时间重新计算一次。造成这种情况的常见原因是 order byjoin 子句不同,这可能取决于发送到方法的数据。

另一个可能查询的结果本身被缓存,一段时间后就失效了。

正如我所说,不看代码就胡乱猜测,但我真的认为检查一下是个好主意。

一种简单的测试方法是检查时间是否会发生变化,如果您一遍又一遍地重复发送完全相同的请求,同时没有发送不同的请求。

希望对您有所帮助。

【讨论】:

【参考方案2】:

这不是角度问题,但这是我解决此问题的方法:

    使用类似chrome extension for a REST API client 的方式向您的端点发出请求。 (您也可以使用类似:http://jmeter.apache.org/,但设置起来更复杂) 运行 20 次并节省时间。 清空数据库并仅填充此请求所需的表 - 仅几行数据。

    运行该工具 20 次 - 存储时间。他们一致吗?如果此时它们不一致,我会将代码视为罪魁祸首。

    您是否在调用任何外部服务? 在加载数据时,除了执行查询之外,服务是否还做其他事情? 使用 dotTrace 之类的分析器来查看花费的时间超出了应有的时间。 (实际上你应该从一开始就使用它)

    如果时间仍然一致,则在数据库中加载更多数据,直到时间开始不一致。然后分析查询并开始优化它们。

现在,由于时间不一致,我会假设该服务在加载该数据时会执行其他操作:外部服务调用.. 某事。

【讨论】:

这对于 OP 来说似乎是一个合理的第一步,但老实说,这里有很多变量在起作用以使其真正有用 - 他将更好地运行诸如 dotTrace 之类的分析器,一瞥甚至两者都真正指出他的问题方向,否则他可能会通过比较自己的测试时间而陷入误报的兔子洞。【参考方案3】:

您编写“完全相同的查询”,但这些查询究竟发生了什么?

您正在查询 SQL Server 数据库吗?

语句看起来如何?

您在查询中还做了什么?

有很多可能的影响,所以为了做出有根据的猜测,我需要一些关于您的查询的更详细信息。

【讨论】:

【参考方案4】:

需要检查/注意的几件事:

1)。你安装了 Glimpse 吗? http://getglimpse.com/ 如果不是,我会从 nuget 安装它,这将使您深入了解整个管道并帮助您追踪这些延迟的来源。

*** 下面是更多通用性能提示 **

2)。您是否在发布到您的服务器时在 Web 配置中禁用了调试?如果不先这样做。我希望您的本地电脑与服务器的行为略有不同,我假设您在本地开发电脑上使用 iis express?它具有与服务器上的 iis 不同的性能特征(虽然我不希望这样),因此不要过度指导这一点。 Glimpse 将在这里成为你最好的朋友 :-)

3)。如上所述,这同样适用于会话状态。如果您没有充分的理由使用它,请将其关闭(默认开启) - 在某些情况下,它可能会成为性能杀手。

【讨论】:

【参考方案5】:

您很可能会看到以下情况之一:

    IIS 应用程序池回收/清理(这可能在设置为在所有内容关闭后回收时发生)

    .NET GC 收集(不太可能)

    SQL Server 相关延迟(查询执行计划缓存和内存数据)

要排除 #3,请尝试在 fiddler 的同时运行 SQL Server 分析器,看看您是否可以识别数据库的延迟(它会确认它在数据库中,或者它会确认数据库响应两种情况都一样)。

对于#2,除了尝试减少内存占用和重用数据结构之外,您实际上无能为力;但如上所述,这不太可能是问题的原因。

使用 #1,您应该能够更改 IIS 配置以确保不会发生这种情况。

【讨论】:

以上是关于ASP.NET WebAPI 和 IIS 中的请求时间不一致的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Web API的安全管道

ASP.NET Web API - 不允许 PUT 和 DELETE 动词 - IIS 8

ASP.NET WebAPI2 CORS:预检时 GetOwinContext 中的空请求

模型绑定不适用于 ASP.NET Core 2 WebAPI 中的 POST 请求

IIS (ASP.NET) 中的请求等待时间稳定

仅在 IIS 中发布时,在 ASP.net Core 3.1 WebAPI 中启用 CORS 时出错