ASP.NET站点自动重启问题排查
来源: 阅读:945 次 日期:2015-04-29 14:09:11
温馨提示: 小编为您整理了“ASP.NET站点自动重启问题排查”,方便广大网友查阅!

项目中遇到的问题

排查原因

最近调试一个东西,写了个监控页面,发现自己Cache的数据在设定的过期时间远远还没有到的时候就过期了,于是我着手排查了下出现问题的原因:

1、程序会删除缓存 -- 查找了整个项目,发现程序里根本没有删除缓存的操作,所以这个原因可以排除。

2、写缓存的方法有问题 -- 这个也可以排除,因为很多地方用这个dll,其它项目不存在这个bug,所以这个原因也可以排除。

3、服务器上有清除所有内存的程序 -- 于是一个个服务终止了下,最后发现终止了一个动转静服务后,程序就没有异常了,所以这个问题是因为动转静服务引起的了。

解决方案

反编译了这个动转静服务的源码,发现并没有清理内存的操作,于是想到了是不是因为动转静服务的什么操作,引起了应用程序池Appliacation_End,然后cache都被回收了。于是在Global.asax里面的Application_End方法里写了下面的代码,用于记录是否引起了这个事件,以及引起事件触发的原因。

protected 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);

if (!EventLog.SourceExists(".NETRuntime"))

{

EventLog.CreateEventSource(".NETRuntime", "Application");

}

EventLog log = new EventLog();

log.Source = ".NET Runtime";

log.WriteEntry(String.Format(" _shutDownMessage={0} _shutDownStack={1}", shutDownMessage, shutDownStack), EventLogEntryType.Error);

}

结果,日志文件里头果然有记录,记录都为:

=====================================================

The description for Event ID ( 0 ) in Source ( .NET Runtime ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event:

_shutDownMessage=Recompilation limit of 15 reached

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.InitiateShutdown()

at System.Web.HttpRuntime.ShutdownAppDomain(String stackTrace)

at System.Web.Compilation.DiskBuildResultCache.ShutdownCallBack(Object state)

at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)

at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state).

=====================================================

$news_page$

网上搜索了一下导致Asp.Net站点重启的原因,具体可以参考:,其中第五条就这样说

修改aspx,master文件不一定会导致重启;但是每修改一次都会导致一次重新编译,重新编译次数达到15次之后会导致站点重启,重启原因是:

Recompilation limit of 15 reached HostingEnvironment initiated shutdown

于是我自己测试了下,停了动转静服务,在运行的项目里面,进行了如下操作

1、对1个Asp.net文件修改了20次以上,发现并没有导致Asp.net站点重启

2、对15个Asp.net文件进行修改,结果就出现了Asp.net站点重启

3、对20个html文件进行修改,发现并没有导致Asp.net站点重启

于是我就纳闷了,动转静导致的都是生成的html文件,并没有修改动态文件,为什么会导致站点重启呢,于是又谷歌了一番,终于又找到个有用的帖子《引起IIS下Asp.net应用程序重启的原因》,这个是翻译过来的文章,原文是

里面的一条这样说道,一个文件夹里同时有很多文件发生改变,.NET系统对这些变化通知来不及反应,这时候可能会重启。比如在高PV时每次访问都生成一次;

仔细想了下,导致我的站点重启的原因最有可能是两个

1、一个文件夹里同时有很多文件发生改变,.NET系统对这些变化通知来不及反应,这时候可能会重启。

2、我Asp.net文件里面会include动转静生成的html文件,可能也被认为是Asp.net文件发生了变化,这个原因感觉是微乎其微,因为include动转静生成文件的asp.net文件不止15个,而且我把动转静的文件个数控制到15个以内的话,居然还是会出现重启的情况,虽然频率降低了。

补充(2013.01.18):今天我特地试了一下方法1,对项目下的任意一个文件进行多文件的覆盖,连续执行n多次,结果发现站点果然重启了。但是好像没有明显的规律,有时候执行两三次就会重启,有时候20多次照样不重启,所以不敢断言就是文件更新造成的。

$news_page$

下面是微软的帮助和支持里面的类似问题的原因和解决方案

微软BUG之多个 ASP.NET 应用程序重新启动出现每隔一至五分钟

症状

很多新的.aspx、.ascx 或.asmx 文件传播到服务器,服务器可能会报告完成后段时间的连续的应用程序重新启动。此问题可能会显示几种不同方式:

为每次重新启动,重新启动 ASP.NETApplication 性能计数器就会增加。

如果使用内存中会话状态,会话变量都将丢失。

应用程序状态都将丢失。

反复执行Application_Start和Application_End事件。

原因

默认情况下当您更新少于 15 个文件在 ASP.NET 中,文件编译和加载到内存中的已编译文件的旧版本。这是.NET 公共语言运行时命名的并行执行的功能。

但是,旧版本的已编译的代码保持无限期地使用通过并行执行的内存中。当您更新多个文件 (例如,30 多个文件),如果不重新启动应用程序以清除内存中的旧版本时,可能使用过多的内存。若要解决此问题,ASP.NET 有一项功能的应用程序将自动重新启动特定数目的文件更新后。

应进行重新启动,一次只能为已更新的文件的完整列表。重新应用程序启动后,旧版本应不驻留在内存中。因此,应用程序应该不需要重新启动以重新编译文件的新版本。但是,加载到服务器 (例如,61 文件) 很多新的.aspx 或.ascx 文件时,将出现此问题。重新服务器卸载前 15 个文件时编译应用程序和每次重新编译另一个文件 15 个直到服务器达到 61。这将导致四个应用程序重新启动,即使只需要其中的。

解决方案

若要避免自动重新启动基于已更新的文件的数量,将numRecompilesBeforeAppRestart属性设置 Machine.config 文件中默认值为 15 为数字的大于计划内的应用程序重新启动之间将更新的文件的数目。如果您将numRecompilesBeforeAppRestart设置为很多,您可能需要重新启动应用程序手动释放旧版本的程序集使用的内存。

注意: 如果 ASP.NET 消耗太多内存,ASP.NET 应用程序自动重新启动。

如果要更新一定数目的文件,并且如果您想要应用程序自动重新启动,设置numRecompilesBeforeAppRestart为一个数字,小于只是将更新的文件的数目。这将导致较少的内存中的旧程序集的单个应用程序重新启动。例如,设置为numRecompilesBeforeAppRestart ,如下所示:

<compilation debug="false" explicit="true" numRecompilesBeforeAppRestart="50" defaultLanguage="vb">

更多信息请查看IT技术专栏

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!

2025国考·省考课程试听报名

  • 报班类型
  • 姓名
  • 手机号
  • 验证码
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map