Dre*_*kes 17 asp.net iis iis-7 application-pool asp.net-mvc-3
我已经在我的机器上部署了一个ASP.NET MVC 3应用程序到共享主机提供程序,并且发现了一些似乎与正在回收的应用程序池相关的问题.主机已配置在以下任何情况下进行回收:
我的开发机器上的限制更加轻松,所以在开发过程中我没有看到像这样的回收.我没有管理员访问共享主机盒(可以理解),所以我无法阅读事件日志,看看为什么这种回收正在发生.
有没有办法可以找出为什么我的应用程序被回收(Application_End
例如),以便我可以记录它来帮助我的调试?
Kev*_*Kev 12
如果没有访问事件日志(因为您处于共享托管环境中),您将获得的最多信息来自Application_End
事件,并通过询问HttpRuntime
(通过反射)一两个私人成员的值,这是令人遗憾的不公开曝光.
为此,请将以下代码添加到您的Application_End
活动中:
BindingFlags staticFlags =
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField;
BindingFlags instanceFlags =
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField;
HttpRuntime runtime = (HttpRuntime)typeof(System.Web.HttpRuntime)
.InvokeMember("_theRuntime", staticFlags, null, null, null);
if(runtime != null)
{
string shutDownMessage = (string)runtime.GetType()
.InvokeMember("_shutDownMessage", instanceFlags, null, runtime, null);
string shutDownStack = (string)runtime.GetType()
.InvokeMember("_shutDownStack", instanceFlags, null, runtime, null);
// Log shutDownMessage & shutDownStack somewhere
}
Run Code Online (Sandbox Code Playgroud)
如果我关闭或回收我的应用程序的应用程序池,我会看到以下内容:
HostingEnvironment initiated shutdown HostingEnvironment caused shutdown - at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace() at System.Web.Hosting.HostingEnvironment.InitiateShutdownInternal() at System.Web.Hosting.HostingEnvironment.InitiateShutdownWithoutDemand() at System.Web.Hosting.PipelineRuntime.StopProcessing()
这可能和它一样好.
更新:
我不记得我在哪里找到了这段代码,但Drew提醒我这是来自Scott Guthrie博客文章.
还有一些其他私人成员可能有用,例如:
private ApplicationShutdownReason _shutdownReason;
Run Code Online (Sandbox Code Playgroud)
您可以在.NET Reflector中检查这些字段(如果您还有一个没有时间轰炸的副本)或其中一个替代方案(Reflector的开源替代方案?).
首先我尝试使用System.Web.ProcessModelInfo.GetCurrentProcessInfo()
和System.Web.ProcessModelInfo.GetHistory(int)
.这些方法的结果返回信息,例如PID,开始时间,年龄,状态和峰值内存使用情况.不幸的是,这些在我的托管环境中不可用
HttpException 0x80004005 - 仅当启用ASP.NET进程模型时,进程度量标准才可用.在工作进程隔离模式下运行IIS 6或更高版本时,不支持此功能.
这种方法可能适用于其他人,所以如果你处于这种情况,那就试一试吧.
该属性System.Web.Hosting.HostingEnvironment.ShutdownReason
是一个包含大量值的枚举,但不幸的是,我在我的问题中概述的所有情况都捆绑在一个枚举值中:
ApplicationShutdownReason.HostingEnvironment
:托管环境关闭应用程序域.
ScottGu在他的博客上有一种方法(这是Kev发布的相同代码),它使用反射来访问内部状态HttpApplication
.不幸的是,在这种情况下,它只报告与上面#2相同的细节:
_shutDownMessage =
HostingEnvironment initiated shutdown
HostingEnvironment caused shutdown
_shutDownStack =
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace()
at System.Web.Hosting.HostingEnvironment.InitiateShutdownInternal()
at System.Web.Hosting.HostingEnvironment.InitiateShutdownWithoutDemand()
at System.Web.Hosting.PipelineRuntime.StopProcessing()
Run Code Online (Sandbox Code Playgroud)
小智 5
下面是从https://mitchelsellers.com/blog/article/logging-asp-net-application-restarts找到的好代码
// obtain the shutdown reason
System.Web.ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason;
string shutdownDetail = "";
//Evaluate which option caused the error
switch (shutdownReason)
{
case ApplicationShutdownReason.BinDirChangeOrDirectoryRename:
shutdownDetail = "A change was made to the bin directory or the directory was renamed";
break;
case ApplicationShutdownReason.BrowsersDirChangeOrDirectoryRename:
shutdownDetail = "A change was made to the App_browsers folder or the files contained in it";
break;
case ApplicationShutdownReason.ChangeInGlobalAsax:
shutdownDetail = "A change was made in the global.asax file";
break;
case ApplicationShutdownReason.ChangeInSecurityPolicyFile:
shutdownDetail = "A change was made in the code access security policy file";
break;
case ApplicationShutdownReason.CodeDirChangeOrDirectoryRename:
shutdownDetail = "A change was made in the App_Code folder or the files contained in it";
break;
case ApplicationShutdownReason.ConfigurationChange:
shutdownDetail = "A change was made to the application level configuration";
break;
case ApplicationShutdownReason.HostingEnvironment:
shutdownDetail = "The hosting environment shut down the application";
break;
case ApplicationShutdownReason.HttpRuntimeClose:
shutdownDetail = "A call to Close() was requested";
break;
case ApplicationShutdownReason.IdleTimeout:
shutdownDetail = "The idle time limit was reached";
break;
case ApplicationShutdownReason.InitializationError:
shutdownDetail = "An error in the initialization of the AppDomain";
break;
case ApplicationShutdownReason.MaxRecompilationsReached:
shutdownDetail = "The maximum number of dynamic recompiles of a resource limit was reached";
break;
case ApplicationShutdownReason.PhysicalApplicationPathChanged:
shutdownDetail = "A change was made to the physical path to the application";
break;
case ApplicationShutdownReason.ResourcesDirChangeOrDirectoryRename:
shutdownDetail = "A change was made to the App_GlobalResources foldr or the files contained within it";
break;
case ApplicationShutdownReason.UnloadAppDomainCalled:
shutdownDetail = "A call to UnloadAppDomain() was completed";
break;
default:
shutdownDetail = "Unknown shutdown reason";
break;
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常晚的答案,但我希望它可以为那些有类似问题(IIS 7.x 或更高版本)的人提供额外的见解。
1. 查找应用程序池何时开始关闭- 以下代码可用于查找应用程序池何时开始关闭。实际关闭发生在此事件后的最大关闭限制(秒,默认为 90)内。
public class ApplicationPoolService : IApplicationPoolService
{
public bool IsShuttingDown()
{
return System.Web.Hosting.HostingEnvironment.ShutdownReason != ApplicationShutdownReason.None;
}
public ApplicationShutdownReason GetShutdownReason()
{
return System.Web.Hosting.HostingEnvironment.ShutdownReason;
}
}
public class HostingEnvironmentRegisteredObject : IRegisteredObject
{
public void Stop(bool immediate)
{
// second call is done when the Stop is imminent
if (immediate)
return;
var reason = appPoolService.GetShutdownReason().ToString();
logger.Log(LogLevel.Info, $"HostingEnvironmentRegisteredObject.stop called with shutdown reason {reason}");
}
}
// this code should be placed in global.asax.cs
protected void Application_Start()
{
HostingEnvironment.RegisterObject(new HostingEnvironmentRegisteredObject());
}
Run Code Online (Sandbox Code Playgroud)
这有助于找到一般原因以及触发的确切时间。在你的情况下,我认为HostingEnvironment
是价值。不幸的是,根本原因并不是唯一的。它可以是定期回收,由于内存限制而回收(OP 问题中最可能的原因),由于固定时间回收等。
2. 查找确切原因-查找确切原因的一种方法是在 EventLog 中搜索。如果无法访问,可以通过提供以下详细信息向托管服务提供商请求以缩小搜索范围。
事件日志应返回更多相关信息,如下所示:
服务应用程序池“xxx”的进程 ID 为“xxx”的工作进程已请求回收,因为它已达到预定的回收时间。
服务应用程序池“xxx”的进程 ID 为“xxx”的工作进程已请求回收,因为它已达到其虚拟内存限制。
归档时间: |
|
查看次数: |
11748 次 |
最近记录: |