【发布时间】:2018-10-11 11:01:37
【问题描述】:
我对 Azure Web 应用程序有一个非常奇怪的问题,对此我感到非常沮丧。
我们体验到我们的应用在使用时非常快速且响应迅速,但是,如果我们在大约十分钟内不使用它,它就会有一个非常冷的启动(约 10-20 秒)。这种冷启动只有在涉及数据库时才会发生。有点像我们发布网络应用的时候。
我们的尝试
使用 Azure 中的 Application Insights,我们每 5 分钟设置一次 ping:
异常值总是由我的部署引起的(现在不使用部署槽)。然而,这个登录页面并没有调用我们的数据库,所以我们在这些数据中看不到“冷启动”。
应用程序设置应该是可靠的。我们的网络应用托管在北欧,Always on:
我们刚刚将整个设置移至新的资源组/应用服务计划,以确保我们的问题与我们的其他应用纠缠在一起。新的应用服务计划是Standard 1 small,应该没有问题。看我们的消费我并不担心,甚至可能会尝试一个较小的服务,我会在解决我们的问题后做:
我们的 SQL 数据库也托管在北欧(检查位置十亿次,因为我以前犯过这个错误)。
就像应用服务一样,我们选择了“太大”的硬件来确保不会导致问题(标准 S0:10 个 DTU)。使用率低得离谱:
我们确实使用持续部署(Azure 菜单中的Deployment options),但看看部署,它不应该持续部署一些东西:
令人沮丧的是,该应用在运行时反应灵敏。当它“温暖”时,每个页面都会在几秒钟内加载,就像我在我们的网络应用上显示的平均响应时间一样:
但是当我们(或我们的用户!)使用我们的应用程序时,这些数字完全是错误的。在这里,我们体验到第一次加载通常是 +10-20 秒。
有人知道吗?有什么提示吗?你不知道我会多么感激。
编辑和更新 1:
我决定设置更多测试。我现在已经设法通过调用另一个页面来获取显示我们问题的真实数据。具有讽刺意味的是,这个页面不调用数据库,所以虽然我认为这是一个数据库问题,但它看起来不像这样。在此处查看挑战(趋势持续 +24 小时)。
奇怪的是,它精确到了大约 10 秒。而且趋势似乎不是每 10-20 分钟一次,而是更接近每 5 分钟一次——它们之间的间隔完全相同:
编辑和更新 2:
我一直在挖掘更多。结果发现有几个非常有趣的见解:来自编辑 1 的“慢”11 秒调用仅来自美国东部和一个端点 (http://prntscr.com/jcv69w),并且
我发现的最有趣的是:
应用程序本身没有任何缓存。我使用实体框架,我假设它使用了一些缓存,但仅此而已。
我登录了我们的应用程序,并在 Chrome 中四处点击。我发现,我已经访问过的页面是即时显示的(使用数据库中的数据),但是如果我打开一个新页面,它会加载缓慢。我第一次打开页面时,似乎有些实体被缓存了。
然后我尝试在新浏览器中打开该应用程序。如果我打开之前在 Chrome 中打开的页面,它会立即打开。如果我打开一个我之前没有点击过的新页面,它的加载时间约为 10 秒。
我现在最好的猜测是我使用的实体框架由于某种原因出现了问题。
编辑 3:
刚刚添加了一个赏金,并且正在设置大量日志记录。我已经添加了 MiniProfiler,但无法让它在生产中工作(仅在本地请求中显示)。
我还为 Application_Start 和 Application_BeginRequest 和 Application_EndRequest 添加了登录 global.asax 以查看其中的一些内容和状态。很快就会更新调查结果。
编辑 4:
所以现在我有了第一个有趣的数字。该应用程序没有被回收。 Application_Start 只被调用一次。
我可以通过登录EndRequest 和BeginRequest 来查看时差。我可以看到这两个之间有多个调用需要超过 +15 秒......但是当网站温暖时,它需要 ~0.5-2 秒,具体取决于页面。所以在请求的开始和结束之间发生了一些非常奇怪的事情。进一步调试!
编辑 5:
让 MiniProfiler 工作。以下是慢速加载的示例(约 15 秒):
我的下一步是添加实体框架跟踪,甚至为线路调用添加更多线路。我在数据库上赚钱!
编辑 6:
Okidoki,我错了。渲染方法很慢 - 而不是数据库!我不知道如何调试这个... 谷歌!
编辑 7:
是时候再更新一次了。状态是:什么都没有解决。
所以我尝试了很多东西:
1) 我尝试禁用所有类型的缓存 (Prevent Caching in ASP.NET MVC for specific actions using an attribute),但我的行为相同。第一次加载?慢。下一个负载?快速地。等待 5-10 分钟,同样的行为没有解决。
2) 我的 startup.auth 文件中有一些自定义内容,延迟了 5 分钟。已移除。不是问题。
3) 我使用自定义属性进行授权。我删除了它。
4) 我更新了我的实体框架实现以使其在每个请求中都能正常工作
我真的很沮丧。我的下一步是:
A) 尝试制作 5-10 个版本的同一页面(没有 _layout,有布局,有数据库,没有数据库,有依赖注入,没有......所有这些东西),所以看看我是否能找到一个模式。
B) 尝试将主机移至虚拟机,看看是否能解决问题
编辑 8 - 添加新遗物:
我现在添加了新遗物。以下是两件非常可怕的事情(我发现并重现了错误!):
在前端方面(New Relic 的浏览器部分),两次启动之间有约 15 秒的间隔:
http://prntscr.com/jevgeg 与 http://prntscr.com/jevgix 之间没有任何区别。
【问题讨论】:
-
github.com/projectkudu/kudu/issues/2583 这是我们在部署槽时遇到的关于冷启动的问题。 TL:DR 尝试仅按照blogs.msdn.microsoft.com/benjaminperkins/2017/11/30/… 的说明使应用程序 HTTPS
-
在此之前,请检查应用洞察 ping URL 和您的用户使用的 URL 是 http 还是 https。我猜一个是http,另一个是https。胡思乱想
-
@GuruCharan94 该应用程序已经仅支持 HTTPS,应用程序洞察力调用 http 版本。不幸的是:)
-
如果 HTTPS only 设置为 ON,则 appinsights ping 应自动重定向到 HTTPS 链接。但是,无论应用程序洞察如何,此“始终开启”功能都应该处理冷启动。目前想不出任何其他解决方案...
-
可以给我们看一下模型和查看代码吗?
标签: asp.net asp.net-mvc azure azure-web-app-service devops