2011-09-16 89 views
0

在最近的壓力和容量測試中,我們意識到30分鐘後,所有用途都會從網站斷開連接。事件記錄後,我們注意到應用程序池崩潰。做一些谷歌調查,顯然在大多數原因這是由於未處理的例外。IIS6應用程序池崩潰

所以當應用程序崩潰,顯示以下異常詳細信息:

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中拋出新的異常...這看起來不正確?如果在此時拋出這個錯誤,誰和什麼會處理這個錯誤?

+0

OKay我可以看到,它不會真的提出一個新的frameworkException,因爲它將打破「FuseFarm.FrameworkException」的情況......但仍然不知道如何解決這個問題。 – FaNIX

+1

異常在需要跨AppDomain邊界時序列化。運行時正試圖爲您序列化它。由於這個原因,所有異常都必須實現'ISerializable'和一個序列化構造器。 – vcsjones

+0

爲什麼甚至在檢查之前已經使用了對象的成員:if(currentException!= null)?無論如何? –

回答

3

它的序列化爲FrameworkException,因爲它試圖穿過AppDomain邊界。

所有穿過AppDomain的對象都必須被序列化,並且異常也沒有區別。

您可以在consider it a bug當一個異常沒有正確實現序列化。

我不相信你的錯誤處理程序是什麼問題的根源。很難判斷堆棧跟蹤 - 完整的內存轉儲會產生更好的信息。

你最好打賭就是properly make the exception serializable

這可能不會完全解決您的問題 - 歸結起來,您仍然會拋出異常。希望一旦這個問題得到解決,你會看到問題的真正原因。

+0

好的,我根據你發佈的文章將我的例外序列化了。將再次做SvT並回報:) – FaNIX

0

如果在Application_Error中引發異常,您的應用程序池將崩潰,就像您看到的一樣。 根據您所顯示的代碼,我的結論是錯誤記錄器在該行稱:

log.Error(currentException.Message, currentException); 

試圖序列化傳遞到它的例外。當currentException結果爲類型FuseFarm.FrameworkException時,錯誤處理程序在該行上崩潰,並且您的應用程序池關閉。

如果是這樣的話,你需要將其標記爲FuseFarm.FrameworkException作爲Serializable,更改記錄器不會嘗試序列化對象,或者把一個try/catch塊在Application_error處理器和做別的事情與這些例外,如果您希望應用程序池繼續前進。

+1

我不認爲'log.Error'是序列化的原因,否則堆棧跟蹤會這樣說。我相信它是運行時試圖跨越AppDomain邊界。 (見http://stackoverflow.com/questions/1066701/why-should-i-always-make-my-exceptions-serializable-net) – vcsjones

+0

@vcsjones,我認爲你是對的。你應該讓你的評論高於一個答案。 –