Application_End应该在自动App Pool Recycle上启动吗? [英] Should Application_End fire on an automatic App Pool Recycle?

查看:192
本文介绍了Application_End应该在自动App Pool Recycle上启动吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读这个这个加上十几个其他帖子/博客。

I have read this, this, this and this plus a dozen other posts/blogs.

我在共享主机中有一个ASP.Net应用程序,经常回收。我们使用NLog并在global.asax中包含以下代码

I have an ASP.Net app in shared hosting that is frequently recycling. We use NLog and have the following code in global.asax

void Application_Start(object sender, EventArgs e) 
{
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    logger.Debug("\r\n\r\nAPPLICATION STARTING\r\n\r\n");
}
protected void Application_OnEnd(Object sender, EventArgs e)
{
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    logger.Debug("\r\n\r\nAPPLICATION_OnEnd\r\n\r\n");
}

void Application_End(object sender, EventArgs e) 
{
        HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic  | BindingFlags.Static  | BindingFlags.GetField,  null,  null,  null);

if (runtime == null)
    return;

string shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage",  BindingFlags.NonPublic  | BindingFlags.Instance  | BindingFlags.GetField,  null,  runtime,  null);

string shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack",   BindingFlags.NonPublic  | BindingFlags.Instance  | BindingFlags.GetField,  null,  runtime,  null);

ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason;

NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
logger.Debug(String.Format("\r\n\r\nAPPLICATION END\r\n\r\n_shutDownReason = {2}\r\n\r\n _shutDownMessage = {0}\r\n\r\n_shutDownStack = {1}\r\n\r\n",
                shutDownMessage, shutDownStack, shutdownReason));
}

void Application_Error(object sender, EventArgs e) 
{
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    logger.Debug("\r\n\r\nApplication_Error\r\n\r\n");

}

我们的日志文件中充斥着APPLICATION STARTING条目,但是 Application_OnEnd Application_End ,以及 Application_Error 都被解雇在这些自发重启期间。我知道他们正在工作,因为有触摸web.config或/ bin文件的条目。我们还运行了一个内存过载测试,可以触发 OutOfMemoryException ,它在 Application_Error 中被捕获。

Our log file is littered with "APPLICATION STARTING" entries, but neither Application_OnEnd, Application_End, nor Application_Error are ever fired during these spontaneous restarts. I know they are working because there are entries for touching the web.config or /bin files. We also ran a memory overload test and can trigger an OutOfMemoryException which is caught in Application_Error.

我们正在尝试确定虚拟内存限制是否导致回收。我们在整个代码中添加了 GC.GetTotalMemory(false),但这适用于所有.Net ,而不仅仅是我们的应用程序池,正确?我们也试过了

We are trying to determine whether the virtual memory limit is causing the recycling. We have added GC.GetTotalMemory(false) throughout the code, but this is for all of .Net, not just our App´s pool, correct? We've also tried

var oPerfCounter = new PerformanceCounter();
oPerfCounter.CategoryName = "Process";
oPerfCounter.CounterName = "Virtual Bytes";
oPerfCounter.InstanceName = "iisExpress";
logger.Debug("Virtual Bytes: " + oPerfCounter.RawValue + " bytes");

但没有共享托管权限。

我在开发服务器上监控了应用程序的相同请求,这些请求导致生产中的循环使用了ANTS Memory Profiler,并且似乎无法找到罪魁祸首。我们还使用dev中附带的调试器运行它来检查生成的线程中可能导致应用程序中止的未捕获异常。

I've monitored the app on a dev server with the same requests that caused the recycles in production with ANTS Memory Profiler attached and can't seem to find a culprit. We have also run it with a debugger attached in dev to check for uncaught exceptions in spawned threads that might cause the app to abort.

我的问题是这些:


  • 如何在应用程序回收之前有效监控共享主机中的内存使用情况,以了解我的应用程序消耗了多少?

  • 为什么不调用global.asax中的Application_ [End / OnEnd / Error]处理程序?

  • 我还能如何确定导致这些循环的原因?

谢谢。

编辑:根据@JaniHyytiäinen的回答

Based on answer by @Jani Hyytiäinen

场景:
线程#1开始,后面跟着线程#2。线程#1达到内存限制但继续处理。线程#3开始。线程#1完成,但#1在#1达到内存限制后超过60秒处理。

Scenario: Thread #1 begins and is followed by thread #2. Thread #1 hits memory limit but continues processing. Thread #3 begins. Thread #1 finishes, but #2 processes more than 60 seconds after #1 has hit the memory limit.

然后游泳池不合理地中止? http响应#2& #3接收(这些是AJAX调用,但我在Fiddler中收到504个错误)?

是否接受了#3的请求,或者只是在新池启动时才排队?

有没有办法知道内存限制已经达到或即将到来?

The pool then ungracefully aborts? What http responses will #2 & #3 receive (These are AJAX calls, but I am getting 504 errors in Fiddler)?
Is the request for #3 accepted or does it just queue until a new pool has started up?
Is there any way to know that the memory limit has been hit or is about to be?

欢迎任何策略。

推荐答案

iis中存在应用程序池关闭时间限制。假设这是60秒,并且在共享托管环境中存在应用程序池内存限制。您的应用程序池达到此限制,iis告诉应用程序池完成当前请求的所有工作。如果所有请求在60秒之前完成处理,则application_end将触发,应用程序池将正常关闭。但是,如果60秒仍然处理并且请求仍在处理中,则IIS会感到不安并杀死应用程序池。这次没有application_end会触发。同样,不会触发错误事件处理程序。

There is an application pool shutdown time limit in iis. Let's say it's 60 seconds and in shared hosting environment there is an application pool memory limit. Your application pool reaches this limit and iis tells the application pool to finish all the work with current requests. If all the requests finish processing before 60 seconds is passed, application_end will trigger and application pool will gracefully shut itself down. However if 60 seconds pass and requests are still being processed, IIS gets upset and kills the app pool. This time no application_end would trigger. Similarly, no error event handler would be triggered.

这篇关于Application_End应该在自动App Pool Recycle上启动吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆