如何使用垃圾回收通知增强 ASP.NET 应用程序的响应性和可扩展性






3.57/5 (3投票s)
本文阐述了一个简单的想法,即如何使用垃圾回收通知来增强 Web 应用程序的性能。
介绍
本文阐述了一个简单的想法,即如何使用垃圾回收通知来增强 Web 应用程序的性能。目前还没有实现。如果有人有足够的时间来实现下面描述的方法,我将很高兴收到结果和反馈。
public static int Main(string[] args){... //method for main ideas
今天使用 .NET Framework 或 Java 编写的所有 Web 应用程序的主要问题是什么? 我认为,是垃圾回收(Garbage Collection)。为了执行 GC,后台 GC 线程需要暂停所有托管线程。这可能需要一段时间,尤其是在 64 位平台上,托管堆大小可能非常大。 这意味着应用程序用户的响应时间更长。 您可能会问“但是我们能做什么呢?”。 我们可以以正确的方式做出反应。 在 .NET Framework 3.5 SP1 中,有一个新的有趣的功能 - 垃圾回收通知。 更多信息可以在 MSDN 这里找到。
如何应对? 让我们考虑一个典型的带有负载均衡器的服务器场景

在这里,我们可以看到前面有几个带有负载均衡器的服务器。 IMHO,在此方案中使用 IIS 6 作为最广泛使用的 ASP.NET 应用程序 Web 服务器。 如图所示,我们可以在Global.asax中的应用程序启动期间订阅 GC 通知。 现在让我们考虑根据负载均衡器的功能集可能使用的解决方案。
- 负载均衡器可以接受来自服务器节点的通知。 在这种情况下,我们的方法非常容易。 当 GC 即将发生时,我们向负载均衡器发送消息“嘿,我将因 GC 而过载”,GC 之后发送消息“好的,准备好了!”。
- LB 用于服务器轮询的时间间隔大于 GC 可能需要的时间。 在这种情况下,我们可以实现自定义 ISAPI 筛选器,每次都会收到 GC 的通知。 如果正在进行 GC,ISAPI 筛选器可以将请求重定向回负载均衡器,以便负载均衡器可以在不同的服务器上重新安排其执行,或者返回一些自定义 HTTP 代码,这对于正确配置的负载均衡器基本上意味着相同。 这里可能存在的问题是,由于 IIS 6 进程模型,自定义 ISAPI 筛选器和我们的 ASP.NET 应用程序将托管在单独的进程中。 这可以通过进程间通信、内存映射文件、允许在特定进程中运行特定方法/函数的 WinAPI 等轻松解决。 您可能会问,为什么是 ISAPI,而不是 HTTP 模块,例如。 答案是在 GC 期间,所有托管线程都会被暂停,因此我们需要一个非托管线程才能成功完成我们的任务。
- LB 用于服务器轮询的时间间隔非常小。 在这种情况下,我们可以配置负载均衡器以轮询自定义 ISAPI 扩展。 为什么不是 HTTP 处理程序? 答案与“ISAPI 筛选器 vs HTTP 模块”的情况相同。 在这里,我们还需要在单独的进程之间进行通信。 负载均衡器将不断轮询我们的自定义 ISAPI 筛选器,以了解服务器端发生的 GC。
摘要
我已经描述了三种基本可能的方法。 当然,可能还有更复杂的方法。 如果您找到更好的方法 - 请告诉我。
历史
- 2009年5月25日:初始发布