加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 如何保护应用程序池免受会话序列化异常的影响?

发布时间:2020-12-16 04:04:12 所属栏目:asp.Net 来源:网络整理
导读:我们正在为ASP.NET应用程序使用进程外会话提供程序(ScaleOut),我们注意到当一个未正确设置反序列化的对象无意中进入会话时,它最终会导致整个终止的过程. 重现和处理这种情况是它变得更有趣的地方. 在AnyStaObjectsInSessionState中引发了终止进程的异常,其实
我们正在为ASP.NET应用程序使用进程外会话提供程序(ScaleOut),我们注意到当一个未正确设置反序列化的对象无意中进入会话时,它最终会导致整个终止的过程.

重现和处理这种情况是它变得更有趣的地方.

在AnyStaObjectsInSessionState中引发了终止进程的异常,其实现非常简单:

internal static bool AnyStaObjectsInSessionState(HttpSessionState session)
{
    if (session != null)
    {
        int count = session.Count;
        for (int i = 0; i < count; i++)
        {
            object obj2 = session[i];
            if (((obj2 != null) && (obj2.GetType().FullName == "System.__ComObject"))
                && (UnsafeNativeMethods.AspCompatIsApartmentComponent(obj2) != 0))
            {
                return true;
            }
        }
    }
    return false;
}

这是堆栈跟踪,显示了异常如何终止进程:

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/1/ROOT

Process ID: 4208

Exception: System.Runtime.Serialization.SerializationException

Message: The constructor to deserialize an object of type 'Lucene.Net.QueryParsers.ParseException' was not found.

StackTrace:    at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj,SerializationInfo info,StreamingContext context)
   at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
   at System.Runtime.Serialization.ObjectManager.DoFixups()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler,__BinaryParser serParser,Boolean fCheck,Boolean isCrossAppDomain,IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream,HeaderHandler handler,IMethodCallMessage methodCallMessage)
   at System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader reader)
   at System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert()
   at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String name,Boolean check)
   at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(Int32 index)
   at System.Web.SessionState.SessionStateItemCollection.get_Item(Int32 index)
   at System.Web.SessionState.HttpSessionStateContainer.get_Item(Int32 index)
   at System.Web.Util.AspCompatApplicationStep.AnyStaObjectsInSessionState(HttpSessionState session)
   at System.Web.HttpApplicationFactory.FireSessionOnEnd(HttpSessionState session,Object eventSource,EventArgs eventArgs)
   at System.Web.SessionState.SessionOnEndTargetWorkItem.RaiSEOnEndCallback()
   at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code,CleanupCode backoutCode,Object userData)
   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)

InnerException: System.Runtime.Serialization.SerializationException

Message: The constructor to deserialize an object of type 'Lucene.Net.QueryParsers.ParseException' was not found.

StackTrace:    at System.Runtime.Serialization.ObjectManager.GetConstructor(Type t,Type[] ctorParams)
   at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj,StreamingContext context)

我们想了解两件事:

> FireSessionOnEnd何时为进程外提供程序启动,更重要的是,我们如何在未加载的开发环境中模仿它?我已经尝试降低会话超时(设置为一分钟),手动调用Abandon(),并手动调用GC.Collect(),都无济于事.
>我们是否可以捕获此步骤中发生的错误以保护应用程序池?这里引发的异常是使用Source = ASP.NET 2.0.50727.0记录的,并且没有到达global.asax中的应用程序错误处理程序.即使经过适当的检查,我们还能做些什么来防范这种情况?余额是否应用于会话绑定对象?

任何见解将不胜感激.

解决方法

我们能够在SOSS技术支持的帮助下解决这个问题 – 它们非常有用 – 以下是详细信息:

>会话到期后,SOSS会在其客户端库中引发过期事件,而后者又负责在Global.asax中触发Session_End(注意:ScaleOut会在客户端之间平衡过期事件,因此创建会话的Web服务器可能无法接收它的到期事件 – 这对于尝试重现这些问题至关重要).
>因为这发生在请求的上下文之外,所以异常未处理并杀死应用程序池;
>这是一个非常罕见的情况,但他们将在即将到来的维护版本中解决这个问题;
>补救措施如下:

>修复System.Exception派生类型(可序列化但不可序列化);>删除Session_EndGlobal.asax中的事件或禁用到期事件(max_event_retries在soss_params.txt中设置为0;>在这些情况下,很可能是用户遇到一个序列化异常之一他们的要求,意味着它到达应用程序错误;在这里你可以清楚会话密钥(必须清除所有他们)或放弃会议彻底;>订阅AppDomain.UnhandledException是通知未处理的例外,它们应该发生(这里没有追索权,只记录);他们也可以通过禁用legacyUnhandledExceptionPolicy(不是推荐的);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读