【问题标题】:IIS6 Application Pool CrashIIS6 应用程序池崩溃
【发布时间】:2011-11-18 08:18:38
【问题描述】:

在最近的压力和容量测试中,我们意识到 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,因为它会在“FuseFarm.FrameworkException”的情况下中断......但仍然不确定如何解决这个问题。
  • 异常在需要跨越 AppDomain 边界时被序列化。运行时正在尝试为您序列化它。因此,所有异常都必须属性实现 ISerializable 和序列化构造函数。
  • 为什么在检查之前就已经使用了对象的成员: if (currentException != null) ?还是?

标签: c# asp.net exception-handling try-catch


【解决方案1】:

它正在序列化FrameworkException,因为它试图跨越 AppDomain 边界。

跨越 AppDomain 的所有对象都必须序列化,例外也不例外。

当异常没有正确实现序列化时,您可以consider it a bug

我不相信您的错误处理程序是问题的根源。鉴于堆栈跟踪,这很难说 - 完整的内存转储会产生更好的信息。

您最好的选择是properly make the exception serializable

这可能无法完全解决您的问题 - 归结起来,您仍然会抛出异常。希望一旦得到纠正,您就会看到问题的真正原因。

【讨论】:

  • 好的,我根据您发布的文章使我的异常可序列化。将再次进行 SvT 并报告:)
【解决方案2】:

如果在 Application_Error 中引发异常,您的应用程序池将崩溃,就像您看到的那样。 根据您显示的代码,我会得出结论,该行中提到的错误记录器:

log.Error(currentException.Message, currentException);

正在尝试序列化传递给它的异常。当currentException 最终成为FuseFarm.FrameworkException 类型时,错误处理程序在该行崩溃并且您的应用程序池关闭。

如果是这种情况,您需要将FuseFarm.FrameworkException 标记为Serializable,将记录器更改为不尝试序列化对象,或者在Application_error 处理程序中放置一个try/catch 块并执行一些操作如果您希望应用程序池继续运行,其他情况除外。

【讨论】:

  • 我不认为log.Error是序列化的原因,否则堆栈跟踪会这样说。我相信这是试图跨越 AppDomain 边界的运行时。 (见stackoverflow.com/questions/1066701/…
  • @vcsjones,我认为你是对的。您应该在答案上方发表评论。
猜你喜欢
  • 2012-03-30
  • 2011-01-16
  • 2010-10-03
  • 1970-01-01
  • 2011-09-26
  • 2013-09-28
  • 2018-04-25
  • 2017-03-14
  • 2011-03-03
相关资源
最近更新 更多