我已经接管了一个现有的MVC网站,该网站使用实体框架和hangfire,并托管在Azure上并使用Azure数据库。网站每隔一段时间就会超时。
我是Azure门户,实体框架和hangfire的新手。
如果我增加DTU,是否可以清除超时问题?
我正在寻找如何诊断网站超时的方法。我使用elmah添加了错误日志记录并检查了hangfire,但这并没有给我任何进一步的信息。
Azure门户中有什么可以帮助您的吗?
答案 0 :(得分:0)
如果它“超时”并且“增加DTU解决了超时”并且这些观察结果是正确的(我想让您自己说服自己这是绝对正确的,请不要轻率做这个假设),那么通常和显而易见的候选人是“慢速SQL查询”。实体框架通常与linq一起使用来创建sql查询,而无需编写sql。这些查询通常适用于非常简单的任务,例如someData.Where(x => x.Id == 1).First(),但是,如果linq用于连接表或创建复杂的关联,则生成的sql可以从性能的角度来看会变得非常糟糕。您可以添加日志记录以写出linq生成的sql,也可以尝试跟踪数据库以查看在其上运行的sql。如果无法进行跟踪,则仍然可以使用元查询来查看诸如缓存的查询计划之类的内容,而SQL Server可以为您提供估计的成本和缓存的执行次数。
您仍然可以在不使用linq的情况下吊死自己。您仍然可以在EF中使用存储过程。太多的开发人员对SQL性能 still 幼稚;您需要梳理后端并学习架构,存储过程;检查所有内容的sql内容。检查是否有任何数据库触发器(容易遗漏)。红旗是子查询,太多的联接,太多的查询结果,查询中的大量字符串处理,联接字符串表或基于XML / JSON的SQL工作。
请注意,当负载较高时,“慢速SQL查询”将变慢。并且,当缓慢的SQL查询建立时,它们只需要花费更多时间来解决。根据查询的性质,这也可能导致破坏表的锁定。
但是查询可以执行,但仍然会导致锁定。即一个表经常被写入,它阻止了对该表的其他写入或读取。这很难诊断,但是您可以通过仔细检查数据库调用日志以及执行它们需要多长时间来解决。您还可以在数据库上运行sql查询,以诊断长时间运行的查询或在给定时间点锁定了哪些表。
最后,检查您的应用程序的任何后端webjob。如果超时发生在重复出现的日期或时间,那么有人的批处理SQL可能会阻止您的生产数据库被读取。
但这只是猜测。我认为您需要做更多的研究,以确定实际上是什么导致该站点无法响应。如果您可以记录常见查询的响应时间,则可以排除基于SQL的延迟是否是罪魁祸首,然后从那里开始工作。您指定的任何技术本质上都不存在“缺陷”。
如果查询确实有效,但仍然引起问题,那么一个长期的解决方案是添加诸如消息队列之类的内容,并以智能方式批处理sql,或者只是使数据库工作为异步而不阻塞UI。
您应该将所有记录的超时与azure的监视相关联。 Azure可以在仪表板上为您提供CPU / RAM /页面访问等。
答案 1 :(得分:0)
SQL Azure有点不同。除非您准备为此付出严重的代价,否则它不具有专用数据库的按需性能。即使如此...
EF,当写得很好时,可以表现的很好。如果写得不好,它可能会很麻烦,而且这些问题在SQL Azure这样的平台上更加复杂。
第一件事是检查您的EF上下文是否设置为使用适合Azure的执行策略:https://docs.microsoft.com/en-us/ef/ef6/fundamentals/connection-resiliency/retry-logic
下一步是查看可以在Azure上运行的哪种SQL跟踪。跟踪对于了解EF在幕后所做的事情至关重要。我对Azure可用的工具不熟悉,在我的情况下,我的Azure经验是在VM上运行SQL Server,因为SQL Azure太不成熟,当时不符合HIPAA,并且对于我们能够获得的DTU估计来说是昂贵的。最坏的情况是,您是否可以将数据库备份还原到SQL Server实例中,并临时将应用程序环境的副本指向该副本以在常见的使用情况下运行?使用SQL跟踪,您可以准确了解EF执行查询的时间和频率以及执行的查询。
要看的东西:
.Select()
可用于减少数据量。甚至在加载与显示/完成的内容无关的整个实体集的情况下,例如有人在.ToList()
或{{1 }}或仅进行.Count()
检查就进行.Any()
。与EF和其他ORM一起开发的常见弊端归结为“拉得太多,太频繁”。令人惊讶的是,与我合作过的客户中有多少开发团队没有使用分析器来检查其ORM使用效率。 (到目前为止,我说的是0%。)