ASP.NET启动性能分析网页

6
我正在尝试确定一个ASP.NET应用程序非常长(在我看来)的初始启动原因。该应用程序使用各种第三方库和大量参考资料,我确信这些资料可以合并,但我正在尝试确定dlls的影响以及它们对扩展启动过程的贡献。
到目前为止,启动时间根据框中其他事物的使用情况而异。根据站点的复杂性,我认为这是不可接受的,我需要将其减少到最多30秒的区域。
要明确我寻找的性能范围,它是从第一个请求到首次访问Application_Start方法的时间。
那么,我从哪里开始获取有关加载哪些DLL以及它们加载所需的时间的信息,以便我可以尝试在哪些方面进行处理/合并的成本效益?
从能力的角度来看,我一直在使用JetBrains dotTrace一段时间,我清楚如何在进入应用程序后对应用程序进行基准测试,但是似乎这超出了应用程序代码,并且超出了我目前所知道的内容。
我正在寻找的是如何获得有关进入我的代码之前发生的情况的可见性的方法。
注意:我知道可以在回收/升级时调用默认页面进行初始加载,但我宁愿解决实际问题而不是掩盖它。
注意2:硬件在功能方面已经足够扩展和分离,因此我相当确定这不是问题的原因。

3
请决定使用“对于项目来说这是不可接受的”还是“在我的观点中这是不可接受的”,因为答案会截然不同:一个是关于如何实现生产应用目标的建议,另一个则涉及如何娱乐/自我教育与负载性能有关的问题。 - Alexei Levenkov
2-5分钟的启动时间可能会满足两个标准。如果应用程序域重新生成并且服务停止2-5分钟,我很难想象有哪个开发人员或项目会认为这是可以接受的。 - Eric J.
我会更新问题,这是在 Application_Start 方法被调用之前的时间。 - Martin
你有没有使用Entity Framework呢?EF的视图创建可能需要几分钟时间。 - JulianR
NHibernate...但我猜这是同样的问题...我相信这将在下面的过程中出现。 - Martin
4个回答

5

关于启动代码的分析和调试:

w3wp只是运行.Net代码的进程,所以您可以使用所有用于普通 .Net 应用程序的分析和调试工具。

一个棘手的问题是,w3wp进程在第一次请求应用程序时就会自动启动,如果您的工具不支持在它启动时附加到该进程,那么就难以调查应用程序的启动代码。

解决问题的诀窍是将另一个应用程序添加到同一应用程序池中。这样,您就可以通过导航到另一个应用程序来触发w3wp进程的创建,然后针对已经运行的进程进行附加/配置您的工具。当您最终触发原始应用程序时,工具将看到现有 w3wp 进程中发生的加载。

在2-5分钟的延迟内,您甚至可能不需要分析器 - 只需按照上述方式附加 Visual Studio 调试器,并在站点加载过程中随机触发“中断所有”几次。很有可能,代码速度最慢的部分将在许多线程的堆栈上。还要注意调试输出 - 它可能会给您提供一些提示。

您还可以使用WinDbg以类似的方式捕获所有线程的堆栈(可能比VS更轻)。


我会尝试几个,然后在确定它捕捉到正确的信息后标记它。 - Martin
似乎 NH 是导致问题的原因...将第二个应用程序添加到同一个应用程序池中使我能够使用 dotTrace 查看东西。 - Martin

2

您的DLL引用是按需加载的,而不是一次性全部加载。

外部引用会减慢我的ASP.NET应用程序吗?(VS:添加引用对话框)

如果启动需要2-5分钟,我会查看Application_Start中发生了什么,以及加载后DLL所做的工作。它们是否试图连接到非常缓慢的远程服务?该机器是否过于小,无法胜任其任务(例如,在AWS微实例或类似实例上运行具有大量数据和Web服务器的DB)?

由于加载时间可能不是IIS工作进程解析引用的问题,因此我会转向传统的应用程序分析器(例如Jetbrains、Antz、dotTrace),以查看在DLL初始化和Application_Start方法中花费的时间。


我使用dotTrace来分析从Application_Start开始的代码,但需要2-5分钟才能到达该点。也许我没有正确设置以查看dll的初始化? - Martin
你控制主要DLL的源代码吗?如果是这样,你可以添加一些简单的日志记录语句...很遗憾我已经很久没有使用dotTrace了。 - Eric J.
我确实控制着网站代码,但不幸的是,问题似乎出现在网站代码之前。否则,我本以为dotTrace会捕获它。 - Martin
1
ANTS Performance Profiler可以对FileI/O进行分析,因此它将向您展示访问诸如.dll之类的文件所花费的时间,具体步骤请参见此处 - Dene B

2

娱乐选项检查和分析:

  • 对所有事物进行分析,添加时间追踪并记录信息
  • 如果您有许多需要在启动时编译的ASPX视图(我认为这是发布配置的默认设置),则需要一些时间
  • 涉及Web服务或其他XML序列化相关代码的引用,如果没有序列化程序集,则需要编译序列化程序集
  • 访问远程服务(包括本地SQL)可能也需要启动服务
  • 应用程序/远程服务中的积极缓存可能需要每个缓存的人口进行填充

生产:

  • 启动时间目标是什么?首先要确定,否则将无法达到目标。
  • 为了减少启动时间,您愿意支付多少代价?增加1-10台服务器可能比花费数月的开发/测试时间并延迟产品的上市更便宜。
  • 考虑使用多个服务器、滚动重启并进行预热调用等方法
  • 如果DB对象或一般情况下的缓存是问题,请考虑使用现有的分布式内存缓存...

我喜欢这个列表,其中第一项有些东西我没有考虑过或者了解过(如序列化程序集、编译 ASPX 页面)。然而,我想要的是能够清楚地看到每个列表项在整个启动过程中所占的成本。 - Martin
我已经在如何调试/剖析ASP.Net启动过程的提示中发布了单独的答案。 - Alexei Levenkov

0
尽管有大量的dll,我几乎可以确定对于一个合理的应用程序来说,它不可能是问题的原因。大多数情况下,静态对象初始化会导致启动缓慢。
在C#中,静态变量在第一次访问类型时被初始化。我建议使用SQL分析器,查看应用程序启动期间执行的查询,然后从那里查看初始化昂贵的对象是什么。

这是我已经走过的路线,似乎没有太多的选择,也没有一个能够获取大型数据集的。 - Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接