我们有一个生产系统,该系统是发布到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(下降)和连接(增加):
我们已经分析了服务器,没有发现与主机(我们只有一个主机)的CPU /内存使用有任何关联,它稳定在20%至30%的CPU使用率和50%的内存使用率。
我们还有另一种遥测数据源,它显示出相同的行为。我们的遥测技术可测量API延迟和数据库指标,例如活动连接数和池连接数(ADO.NET连接池):
有趣的是,每个系统停顿都伴随着池连接数量的增加。我们的测试表明,连接池越多,您花费在等待来自该池的新连接上以执行下一个数据库操作的时间就越长。我们分析了一些建议,但无法证明或反驳其中的任何一个:
截至目前,我们正在尝试确定这种行为的可能原因。不幸的是,由于缺少遥测技术,我们无法确定导致其变化的原因,因此,解决此问题的唯一方法是正确诊断它。而且,当然,我们只能在永久负载下(即使负载不高,例如每秒请求10个负载)在生产中复制它。
此行为的可能原因是什么,以及对其进行诊断和故障排除的正确方法是什么?
可能有几种原因:
问题可能出在您的应用程序代码中,创建了一个暂存环境,然后使用探查器工具遥测(即,使用YourKit .NET Profiler)重新运行测试-这将使您能够检测到最繁重的方法,最大的对象,最慢的数据库查询等等。还可以使用JMeter对您的API进行负载测试。
[我建议您尝试使用Kudu Process API来查看当前正在运行的进程的列表,并获取有关它们的更多信息并列出其CPU时间。
下面显示了如何在Azure App服务中监视CPU使用情况的文章:
https://azure.microsoft.com/en-in/documentation/articles/web-sites-monitor/
https://azure.microsoft.com/en-in/documentation/articles/app-insights-web-monitor-performance/