不可预测的API请求发布到Azure Web App的ASP.NET Web API中的延迟高峰

Dre*_*ile 7 entity-framework connection-pooling azure asp.net-web-api azure-sql-database

我们有一个生产系统,该系统是发布到的ASP.NET Web API(经典的,不是.NET Core)应用程序Azure。数据存储是Azure SQL Database,我们Entity Framework用来访问数据。API具有中等负载,每秒10-60个请求,upper_90延迟为100-200毫秒,这是我们的情况。不久前,我们注意到大约每20-30分钟我们的服务就会停顿,并且延迟会跳到大约5-10秒。所有请求开始缓慢运行约一分钟,然后系统自行恢复。同时没有丢弃任何请求,它们都将花费更长的时间来执行。短时间(通常为1分钟)。

我们开始在HTTP请求遥测(Azure)中看到以下图片:

网络应用延迟

我们还可以看到与Azure SQL数据库指标的相关性,例如DTU(删除)和连接(增加):

db dtu和连接

我们已经分析了服务器,没有发现与主机(我们只有一个主机)的CPU /内存使用有任何关联,它稳定在20-30%的CPU使用率和50%的内存使用率。

我们还有另一种遥测数据源,它显示出相同的行为。我们的遥测技术可测量API延迟和数据库指标,例如活动连接数和池连接数(ADO.NET连接池):

自我监控确认

有趣的是,每个系统停顿都伴随着池连接数量的增加。我们的测试表明,连接池越多,您花费在等待来自该池的新连接上以执行下一个数据库操作的时间就越长。我们分析了一些建议,但无法证明或反驳其中的任何一项:

  1. ADO.NET连接泄漏(我们所有的数据库访问发生在using语句中,并且具有正确的连接处置/返回池)
  2. 套接字/端口耗尽-无法正确跟踪该度量标准的遥测
  3. CPU /内存瓶颈-图表显示没有瓶颈
  4. DTU(数据库单位)瓶颈-图表显示没有瓶颈

到目前为止,我们正在尝试确定这种行为的可能原因。不幸的是,由于缺少遥测技术,我们无法确定导致其变化的原因,因此,解决此问题的唯一方法是正确诊断它。而且,当然,我们只能在永久负载下(即使负载不高,例如每秒请求10个负载)在生产中进行复制。

有什么可能导致这种现象,正确的诊断和排除故障的方法是什么?

Dre*_*ile 1

我们最终将一些 Web 应用程序托管在一个应用程序服务计划中。尽管这些指标没有向我们显示应用程序上的 CPU 存在任何瓶颈,但还有其他应用程序会导致 CPU 使用率峰值,从而导致连接池队列增长并导致巨大的延迟峰值。

当我们检查应用服务计划使用情况并将其与数据库计划使用情况进行比较时,很明显瓶颈在于应用服务计划。虽然 CPU 瓶颈导致不均匀的延迟峰值,但仍然很难解释,但我们决定将负载最多的 Web 应用程序分离到单独的计划中并单独处理。分离后,应用程序表现正常,没有 CPU 或延迟峰值,并且看起来非常稳定(与峰值之间的情况相同):

网络 API 延迟 应用程序服务计划CPU使用率

我们将继续分析其他应用程序,最终会找到罪魁祸首,但此时关键任务 Web 应用程序是孤立的并且非常稳定。这里的教训是不仅要监控 Web 应用程序资源使用情况,还要监控托管应用程序服务计划,该计划可能会让其他应用程序消耗资源(CPU、内存)