ASP.NET启动性能分析Web

时间:2022-06-01 18:54:48

I'm trying to determine the cause of a very long (imho) initial start up of an ASP.NET application.

我正在尝试确定一个非常长的(imho)初始启动ASP.NET应用程序的原因。

The application uses various third party libraries, and lots of references that I'm sure could be consolidated, however, I'm trying to identify (and apportion blame) the dlls and how much they contribute to the extended startup process.

该应用程序使用各种第三方库,并且我确信可以合并许多引用,但是,我正在尝试识别(并分配责任)dll以及它们对扩展启动过程的贡献。

So far, the start up times vary from 2-5 minutes depending on usage of other things on the box. This is unacceptable in my opinion based on the complexity of the site, and I need to reduce this to something in the region of 30 seconds maximum.

到目前为止,启动时间从2-5分钟不等,具体取决于盒子上其他东西的使用情况。基于网站的复杂性,我认为这是不可接受的,我需要将其减少到最大30秒的范围内。

To be clear on the scope of the performance I'm looking for, it's the time from first request to the initial Application_Start method being hit.

为了清楚我正在寻找的性能范围,它是从第一个请求到初始Application_Start方法被击中的时间。

So where would I start with getting information on which DLL's are loaded, and how long they take to load so I can try to put a cost/benefit together on which we need to tackle/consolidate.

那么我将从哪里开始获取有关加载哪些DLL的信息,以及加载所需的时间,以便我可以尝试将成本/收益放在一起,以便我们需要解决/整合。

From an ability perspective, I've been using JetBrains dotTrace for a while, and I'm clear on how benchmark the application once we're in the application, but it appears this is outside of the application code, and therefore outside of what I currently know.

从能力的角度来看,我已经使用了JetBrains dotTrace一段时间了,而且我很清楚应用程序在应用程序之后如何对应用程序进行基准测试,但它看起来不在应用程序代码之内,因此在我目前知道。

What I'm looking for is methodologies on how to get visibility of what is happening before the first entry point into my code.

我正在寻找的是如何在第一个入口点进入我的代码之前了解正在发生的事情的方法。

Note: I know that I can call the default page on recycle/upgrade to do an initial load, but I'd rather solve the actual problem rather than papering over it.

注意:我知道我可以在回收/升级上调用默认页面来进行初始加载,但我宁愿解决实际问题而不是通过它来解决问题。

Note2: the hardware is more than sufficiently scaled and separated in terms of functionality, therefore I'm fairly sure that this isn't the issue.

注2:硬件在功能方面有足够的扩展和分离,因此我很确定这不是问题。

4 个解决方案

#1


2  

Separate answer on profiling/debugging start up code:

关于分析/调试启动代码的单独答案:

w3wp is just a process that runs .Net code. So you can use all profiling and debugging tools you would use for normal .Net application.

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

One tricky point is that w3wp process starts automatically on first request to an application and if your tools do not support attaching to process whenever it start it makes problematic to investigate startup code of your application.

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

Trick to solve it is to add another application to the same Application Pool. This way you can trigger w3wp creation by navigating to another application, than attach/configure your tools against already running process. When you finally trigger your original application tools will see loading happening in existing w3wp process.

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

With 2-5 minutes delay you may not even need profiler - simply attach Visual Studio debugger the way suggested above and randomly trigger "break all" several times during load of your site. There is a good chance that slowest portion of the code will be on the stack of one of many threads. Also watch out for debug output - may give you some clues what is going on.

延迟2-5分钟您可能甚至不需要分析器 - 只需按照上面建议的方式连接Visual Studio调试器,并在加载站点期间随机触发“全部中断”几次。代码的最慢部分很可能会出现在许多线程之一的堆栈上。还要注意调试输出 - 可能会给你一些线索。

You may also use WinDbg to capture stacks of all threads in similar way (could be more light way than VS).

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

#2


2  

Your DLL references are loaded as needed, not all at once.

您的DLL引用是根据需要加载的,而不是一次加载。

Do external references slow down my ASP.NET application? (VS: Add Reference dialog)

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

If startup is taking 2-5 minutes, I would look at what happens in Application_Start, and at what the DLLs do once loaded. Are they trying to connect to a remote service that is very slow? Is the machine far too small for what it's doing (e.g. running a DB with large amounts of data plus the web server on an AWS micro instance or similar)?

如果启动需要2-5分钟,我会看看Application_Start中发生了什么,以及DLL在加载后执行的操作。他们是否尝试连接到非常慢的远程服务?机器是否太小而无法正常运行(例如,运行具有大量数据的数据库以及AWS微型实例上的Web服务器等)?

Since the load time is probably not the IIS worker process resolving references, I would turn to traditional application profilers (e.g. Jetbrains, Antz, dotTrace) to see where the time is being spent as the DLLs initialize, and in your Application_Start method.

由于加载时间可能不是IIS工作进程解析引用,我将转向传统的应用程序分析器(例如Jetbrains,Antz,dotTrace)来查看DLL初始化时的时间以及Application_Start方法。

#3


1  

Entertainment options check along with profiling:

娱乐选项检查以及分析:

  • profile everything, add time tracing to everything and log the information
  • 配置所有内容,为所有内容添加时间跟踪并记录信息
  • if you have many ASPX views that need to be compiled on startup (I think it is default for release configuration) than it will take some time
  • 如果你有许多需要在启动时编译的ASPX视图(我认为它是发布配置的默认值)而不是需要一些时间
  • references to Web services or other XML serialization related code will need to compile serialization assemblies if none are present yet
  • 如果尚不存在,那么对Web服务或其他XML序列化相关代码的引用将需要编译序列化程序集
  • access to remote services (including local SQL) may require the services start up too
  • 访问远程服务(包括本地SQL)可能也需要启动服务
  • aggressive caching in application/remote services may require per-population of caches
  • 应用程序/远程服务中的积极缓存可能需要每个群体的缓存

Production:

生产:

  • What is the goal for start up time? Figure out it first, otherwise you will not be able to reach it.
  • 启动时间的目标是什么?首先弄清楚它,否则你将无法达到它。
  • What is price you are willing to pay to decrease start up time. Adding 1-10 more servers may be cheaper than spending months of development/test time and delaying the product.
  • 您愿意为减少启动时间而支付的价格是多少。增加1-10个服务器可能比花费数月的开发/测试时间和延迟产品更便宜。
  • Consider multiple servers, rolling restarts with warm up calls, web gardens
  • 考虑多个服务器,通过热身呼叫滚动重启,网络花园
  • If caching of DB objects or in general is an issue consider existing distributed in-memory caches...
  • 如果缓存数据库对象或一般来说是一个问题,请考虑现有的分布式内存缓存......

#4


0  

Despite a large number of dlls I'm almost sure that for a reasonable application it cannot be a cause of problem. Most of the time it is static objects initialization is causing slow startup.

尽管有大量的dll我几乎可以肯定,对于合理的应用程序来说,它不能成为问题的原因。大多数情况下,静态对象初始化导致启动缓慢。

In C# static variables are initialized when a type is first time accessed. I would recommend to use a sql profiler and see what are the queries that are performed during the start time of the application and from there see what are the objects that are expensive to initialized.

在C#中,首次访问类型时会初始化静态变量。我建议使用sql profiler,看看在应用程序的开始时间执行的查询是什么,从那里看看哪些对象的初始化成本很高。

#1


2  

Separate answer on profiling/debugging start up code:

关于分析/调试启动代码的单独答案:

w3wp is just a process that runs .Net code. So you can use all profiling and debugging tools you would use for normal .Net application.

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

One tricky point is that w3wp process starts automatically on first request to an application and if your tools do not support attaching to process whenever it start it makes problematic to investigate startup code of your application.

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

Trick to solve it is to add another application to the same Application Pool. This way you can trigger w3wp creation by navigating to another application, than attach/configure your tools against already running process. When you finally trigger your original application tools will see loading happening in existing w3wp process.

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

With 2-5 minutes delay you may not even need profiler - simply attach Visual Studio debugger the way suggested above and randomly trigger "break all" several times during load of your site. There is a good chance that slowest portion of the code will be on the stack of one of many threads. Also watch out for debug output - may give you some clues what is going on.

延迟2-5分钟您可能甚至不需要分析器 - 只需按照上面建议的方式连接Visual Studio调试器,并在加载站点期间随机触发“全部中断”几次。代码的最慢部分很可能会出现在许多线程之一的堆栈上。还要注意调试输出 - 可能会给你一些线索。

You may also use WinDbg to capture stacks of all threads in similar way (could be more light way than VS).

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

#2


2  

Your DLL references are loaded as needed, not all at once.

您的DLL引用是根据需要加载的,而不是一次加载。

Do external references slow down my ASP.NET application? (VS: Add Reference dialog)

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

If startup is taking 2-5 minutes, I would look at what happens in Application_Start, and at what the DLLs do once loaded. Are they trying to connect to a remote service that is very slow? Is the machine far too small for what it's doing (e.g. running a DB with large amounts of data plus the web server on an AWS micro instance or similar)?

如果启动需要2-5分钟,我会看看Application_Start中发生了什么,以及DLL在加载后执行的操作。他们是否尝试连接到非常慢的远程服务?机器是否太小而无法正常运行(例如,运行具有大量数据的数据库以及AWS微型实例上的Web服务器等)?

Since the load time is probably not the IIS worker process resolving references, I would turn to traditional application profilers (e.g. Jetbrains, Antz, dotTrace) to see where the time is being spent as the DLLs initialize, and in your Application_Start method.

由于加载时间可能不是IIS工作进程解析引用,我将转向传统的应用程序分析器(例如Jetbrains,Antz,dotTrace)来查看DLL初始化时的时间以及Application_Start方法。

#3


1  

Entertainment options check along with profiling:

娱乐选项检查以及分析:

  • profile everything, add time tracing to everything and log the information
  • 配置所有内容,为所有内容添加时间跟踪并记录信息
  • if you have many ASPX views that need to be compiled on startup (I think it is default for release configuration) than it will take some time
  • 如果你有许多需要在启动时编译的ASPX视图(我认为它是发布配置的默认值)而不是需要一些时间
  • references to Web services or other XML serialization related code will need to compile serialization assemblies if none are present yet
  • 如果尚不存在,那么对Web服务或其他XML序列化相关代码的引用将需要编译序列化程序集
  • access to remote services (including local SQL) may require the services start up too
  • 访问远程服务(包括本地SQL)可能也需要启动服务
  • aggressive caching in application/remote services may require per-population of caches
  • 应用程序/远程服务中的积极缓存可能需要每个群体的缓存

Production:

生产:

  • What is the goal for start up time? Figure out it first, otherwise you will not be able to reach it.
  • 启动时间的目标是什么?首先弄清楚它,否则你将无法达到它。
  • What is price you are willing to pay to decrease start up time. Adding 1-10 more servers may be cheaper than spending months of development/test time and delaying the product.
  • 您愿意为减少启动时间而支付的价格是多少。增加1-10个服务器可能比花费数月的开发/测试时间和延迟产品更便宜。
  • Consider multiple servers, rolling restarts with warm up calls, web gardens
  • 考虑多个服务器,通过热身呼叫滚动重启,网络花园
  • If caching of DB objects or in general is an issue consider existing distributed in-memory caches...
  • 如果缓存数据库对象或一般来说是一个问题,请考虑现有的分布式内存缓存......

#4


0  

Despite a large number of dlls I'm almost sure that for a reasonable application it cannot be a cause of problem. Most of the time it is static objects initialization is causing slow startup.

尽管有大量的dll我几乎可以肯定,对于合理的应用程序来说,它不能成为问题的原因。大多数情况下,静态对象初始化导致启动缓慢。

In C# static variables are initialized when a type is first time accessed. I would recommend to use a sql profiler and see what are the queries that are performed during the start time of the application and from there see what are the objects that are expensive to initialized.

在C#中,首次访问类型时会初始化静态变量。我建议使用sql profiler,看看在应用程序的开始时间执行的查询是什么,从那里看看哪些对象的初始化成本很高。