ASP.NET下Session相关问题的处理

来源:互联网 发布:怎么在mac上卸载程序 编辑:程序博客网 时间:2024/06/05 12:47

翻译自:http://aspalliance.com/1182_Troubleshooting_Session_Related_Issues_in_ASPNET

版权归原文作者所有,转载请注明出处

ASP.NETSession相关问题的处理

 

简介

当你的站点出现了session丢失(比如:在你的电子商务站点,用户采购了25件商品,当他准备结帐的时候,却被定向到了登陆页面!),顾客和老板会很不开心,这将对业务带来灾难性影响。

有时这类问题可能非常诡异。通常我的解决方式是:询问一些相关的问题,然后修正它。下面是一些典型问题:

问题

1Session丢失的时候,到底发生了些什么?浏览站点的客户是否突然被注销并重定向到登陆页面(或者是否做了什么特别的操作导致注销)?

回答:多种多样,因为这是一个开放性的问题

可能是session超时或者session丢失或其他任何原因!唯一可以确定的是,需要问更多的问题来逐渐缩小范围。

2:是否随机发生?可以随时重现么?

回答:如果答案是随机发生(大多数情况下),那么跳到问题3。如果可以重现,太好了,跳到问题4。基本上,如果可以重现问题,剩下的事情就是反复尝试重现错误,然后修复。

根据问题是否可重现,无需实际操作,我们已经可以找到着力点了

3:我们知道问题是随机发生的,现在需要知道是否所有用户在同一时间注销,要是只有几个用户或者所有的用户都是随机注销的话,就麻烦了。

回答:对我而言,这个问题是最重要的。我将告诉你为什么。

如果所有用户在同一时间注销,那么有两种可能性:应用程序域回收或者工作者进程(XP 2000 aspnet_wp.exe 2003 w3wp.exe  )崩溃。

 

现在的问题是:如何得知哪种情况可能性最大

应用程序域回收?

可以在服务器上按如下步骤添加性能计数器以获得信息

点击 开始菜单->运行,输入perform,确定

展开 性能日志和警报,在计数器日志上 选择  新建日志设置,输入名称然后确定

点击 添加计数器 按钮

在性能对象中选择 ASP.NET v.1.1.4322 或者相应版本的ASP.NET对象

在对象列表中选择Application Restarts,确定。

你将注意到数据开始记录至日志文件。

一旦应用程序域回收(所有用户同时注销),右击计数器日志文件,然后点击 停止。

如果点击右键并选择 属性,系统会显示日志文件的路径,默认情况下,是c:/Perflogs,路径是可以自行设置的。

接着用监视器打开日志文件,添加 Application Restarts 计数器

 

一般情况下,我们看到的是任何原因导致的应用程序重启,如果重启次数大于0,将看到阶梯状的曲线图,如下:

 

我通过改动web.config让应用程序重启。注意我调整了比例尺,让图好看一些。

如果你看到这些,说明ASP.NET应用程序由于web,config或者machine.config,global.asaxbin目录或多个aspx文件改动而重启。如果是这样请看下面的场景。

 

场景:

 

杀毒软件

在我看来,将框架和应用程序目录从杀毒软件的扫描计划中排除掉,是最好的法子。

机器上运行的任何备份程序或者索引服务,都可能导致web应用程序目录发出文件更改通知(FCNFile Change Notification)。你可以将web应用程序从中排除掉(如果提供了这个选项的话)或者干脆停用备份或者索引服务.

组策略

删除ASP.NET 2.0 应用程序的子目录

根据我的经验,甚至上传文件到服务器都会导致session丢失。最简便的解决办法是将上传内容保存在应用程序目录之外。

 

迁移到ASP.NET 2.0之后session丢失

丢失session变量并且应用程序域回收

如果尝试了上面的1-6个步骤之后,应用程序域仍然由于奇怪的原因而回收,是时候将session模式切换到States erver了,SQL模式也可以,但出于排除问题的考虑,ASP.NET State server 就很好。关于进程模式的更多信息,可以看这里

如果在用ASP.NET 2.0,有更好的办法检查应用程序,回收无需创建性能监视器日志。具体查看这里:Health Monitoring for Application's lifetime related events.

 

进程崩溃?

检查事件查看器,看是否有ID1000的应用程序错误。了解更多关于崩溃和如何修正它的信息,请查看我的博客:http://blogs.msdn.com/rahulso/archive/2006/03/02/541737.aspx。也可以查看Tess blog来学习调试崩溃相关问题的知识。

由于应用程序池相关的设置而导致工作者进程回收(如果在使用2003服务器版的话)

确保已经禁用了所有进程相关的回收选项。默认情况下,应用程序池(iis 6)设置为每29小时或连续20分钟不活动就回收。

查看关于IIS 6应用程序池相关的设置,请查看这篇文章

 

零星的问题

如果问题是在某些用户中零星的发生。那么事情就更棘手了。现在需要搞清楚是某特定用户还是多个用户(不是同时发生)有这个问题。如果是某个特定用户经常碰到,意味着什么呢?正如你猜测的,可能与客户端设置或操作有关。应该问以下问题以决断并进一步隔离问题。

用户是否在特地的机器上遭遇同样的问题?

或许用户没有尝试过从不同机器上访问这个站点。可能的话,请用户尝试这么做(比如,用户使用的是XP,可以让他用其他操作系统访问)。因为用户的系统可能使用了特殊的设置。当然也可以检查改机器设置,但为什么要在没有证据的情况下在用户机器上浪费时间呢?如果用户说问题仅仅在他的机器上出现,你又可以重现这个问题,就可以深挖出问题根源了,可能是硬件/软件导致的。

目前为止,干得不错!

 

为什么说是硬件(网线/路由 等等)或软件(浏览器设置/机器策略)引起的呢?我建议使用其它浏览器,比如Mozilla来验证。若其他浏览器工作正常,那么一定是IE设置的问题。从Cookie相关设置入手,检查是否internet临时文件空间不足,cookie数量等。有一个叫做Fiddler的工具(是一个http调试代理工具)可以帮你检查故障机器的设置。也可以使用网络监视器跟踪并找出问题所在。我写了篇关于这方面的博客 how to fix cookie related issues

  还有可能是用户帐号相关代码引起的(如果代码根据某些要素检查了特定用户的话)。应该根据应用程序架构来采取ASP.NET跟踪或者调试技术来检查这些代码。

  假如是所有的用户都有这个问题,但不是在同一时间。OK,很容易猜到是服务器的问题。现在已经证明应用程序域没有回收,工作进程也没有崩溃,那会是什么问题呢?

 

注意:并不是所有的用户同一时间发生问题。是所有用户,但并不是同一时间!

 

WEB FARM

让我们看看使用WEB FARM时发生了什么。设想,客户端访问服务器XX拥有用户的session,下词还是访问X,没问题。过了1015分钟之后,由于负载的关系,用户被切换到YY不知道用户是谁,于是定向到登陆页面。同样的事情可能在所有访问这个站点的用户中发生。这种情况下,我们必须使用进城外session模式,可以是ASP.NET State Server SQL Server 。如果仍然丢失session,想象一下会发生什么?

我建议执行以下的检查:

1.  IIS中,web farm下所有站点的名字必须相同(注意,名字是大小写敏感的)。更多细节,请查看KB

2.  框架目录下(C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/CONFIG)machine.config中有一个键,包含了下面的默认设置:

<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="SHA1"/>

 

如果计划使用web farm,必须确保machineKeywin 2003除外)节点的validationKey以及decryptionKey属性不被设置为AutoGenerate。下面的知识库文章演示了如何在VB C# 下做到这点。

3.如果使用Web garden而不是Web farm,在machine.config中有一个叫做Web Garden的属性,应该设置为true,同时必须使用上面讨论过的进城外session模型。Win 2003操作系统下web garden不使用这个设置,它使用应用程序池设置。更多

 

 问题4:问题可以重现,首先该做的事情是弄清是本应用程序还问题是所有应用程序都有问题。

回答: 考虑以下的场景:

如果所有的程序都有类似的问题。意味着所有的程序都无法保持session信息。是的,相信我,这完全可能!!见过这样的例子,由于不好的服务器名字导致问题频繁发生。举个例子,如果服务器名包含下划线或者特殊字符,将无法保持sessioncookie信息。检查 知识库文章 以确保没有这个问题。

除一个页面无法保持session之外,所有的页面都没有问题。这说明有坏对象。建议首先备份问题页面。然后注释掉所有保存session的语句。完成后,页面恢复正常。然后,添加一个虚拟的session变量看是否正常。因为其他页面正常,我非常肯定添加虚拟的session变量也不会有问题。不过,做这个测试还是值得的。一旦这个变量有效,就可以一行接一行的取消对之前代码的注释,很快就会找到导致问题的变量,修正这个对象就可以了。

 

最近碰到了一个非常有趣的问题。那是一个购物车程序,每次当用户添加第20个商品到cookie之后就会发生session丢失。每次都是在第20个之后。我决定看带cookieIIS日志。

有如下的session IDASPSESSIONIDSSAQTADR=PKCFNDFCAJPLBEPHCBJCDNPP。每次选择物品并添加信息到cookie20个之后session ID被移除,session丢失。查看知识库文章 ,注意到每个唯一的主机或域名下至多只能保存20cookie。所以,由于客户端有限制会丢失session

绝大部分情况下,都可以用上面提到的技巧来解决session相关的问题。希望本文对你有所帮助。

 

参考文章

 

ASP.NET State Management Overview

Session State

Understanding session state modes + FAQ

Underpinnings of the Session State Implementation in ASP.NET