IIS6应用程序池崩溃
本文关键字:崩溃 程序池 应用程序 应用 IIS6 | 更新日期: 2023-09-27 18:08:50
在最近的压力和容量测试中,我们意识到30分钟后,所有用户都与网站断开连接。在记录事件之后,我们注意到应用程序池崩溃了。做一些谷歌调查,显然在大多数原因,这是由于未处理的异常。
所以当应用程序崩溃时,将显示以下异常详细信息:
An unhandled exception occurred and the process was terminated.
Application ID: DefaultDomain
Process ID: 7852
Exception: System.Runtime.Serialization.SerializationException
Message: Type 'FuseFarm.FrameworkException' in Assembly 'FuseFarm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
StackTrace: at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeObject(Object obj, MemoryStream stm)
at System.AppDomain.Serialize(Object o)
at System.AppDomain.MarshalObject(Object o)
我不知道为什么它试图序列化FrameworkException,而且我无法在代码中看到这是在做什么。但我确实看到有几部分代码
new FrameworkException(exData, "ContractComposition.SubmitContract");
正在被调用,但没有被处理。在检查global.asax.cs之后,会发生以下情况:
protected void Application_Error(object sender, EventArgs e)
{
ILog log = LogManager.GetLogger(typeof(Global));
string environmentName = WebConfigurationManager.AppSettings["EnvironmentName"];
if (!String.IsNullOrEmpty(environmentName) && (environmentName == "DEMO" || environmentName == "LIVE"))
{
Exception currentException = Server.GetLastError().GetBaseException();
Session["errorMessage"] = currentException.Message;
Session["errorSource"] = currentException.Source;
Session["errorTrace"] = currentException.StackTrace;
log.Error(currentException.Message, currentException);
if (currentException != null)
{
Session["error"] = currentException.GetType().Name;
switch (currentException.GetType().ToString())
{
case "System.ApplicationException":
case "FuseFarm.FrameworkException":
break;
default:
new FrameworkException(currentException.Message + "'n" + currentException.StackTrace, currentException.Source, currentException);
break;
}
}
Server.Transfer("~/error.aspx");
}
}
在Application_Error中抛出新的异常…这看起来不对吗?如果此时抛出这个错误,谁和什么将处理这个错误?
正在序列化FrameworkException
,因为它试图跨越AppDomain边界。
所有穿过AppDomain的对象都必须被序列化,异常也不例外。
当一个Exception没有正确实现序列化时,你可以认为它是一个bug。
我不相信你的错误处理程序是问题的根源。考虑到堆栈跟踪,很难判断——一个完整的内存转储将产生更好的信息。
最好的办法是适当地使异常可序列化。
这可能不能完全解决你的问题——总而言之,你仍然会抛出异常。希望一旦这个问题得到纠正,您就会看到问题的真正原因。
如果Application_Error抛出异常,你的应用程序池将崩溃,就像你看到的那样。根据您所展示的代码,我可以得出如下结论:
这行中引用的错误日志记录器log.Error(currentException.Message, currentException);
试图序列化传递给它的异常。当currentException
最终为FuseFarm.FrameworkException
类型时,错误处理程序在该行崩溃,并且您的应用程序池关闭。
如果是这种情况,您需要将FuseFarm.FrameworkException
标记为Serializable
,更改日志记录器以不尝试序列化对象,或者在Application_error
处理程序中放置一个try/catch块,如果您希望应用程序池继续运行,则使用这些异常做其他事情。