<sessionState
mode="SQLServer"
allowCustomSqlDatabase="true"
sqlConnectionString="server=192.168.9.151; DataBase=MyAspState;uid=sa; pwd=123456;"
/>
六.使用经验与技巧总结
下面是SessionID, Session_End时间, StatServer模式 和 SqlServer模式的各种经验和技巧总结.
(1)StateServer模式:
1.在web farm中,请确认在所有的web服务器上有相同的<machineKey>
2. 要保存在Session中的对象是可序列化的。
3.为了在web farm中的不同web服务器上维护session state,IIS Metabase中的网站应用程序路径(如\LM\W3SVC\2)应该在所有的服务器上保持一致(大小写敏感).
4. ASP.NET处理Session是在Machine.Config中配置的HttpModuel模块, 在.NET的安装目录下的Config文件夹中, 查看Web.Config(1.1版本是在Machine.Config):
复制代码 代码如下:
<httpModules>
... <add type="System.Web.SessionState.SessionStateModule"/>
... </httpModules>
确认此模块是否存在.
5.StateServer不支持负载均衡, 所以如果大并发推荐使用SqlServer模式, 可以享受到SqlServer的高性能和安全性.虽然存储效率会有下降.
6.需要让所有机器的MachineKey相同.在Machine.Config中配置:
复制代码 代码如下:
<machineKey
validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"
decryptionKey="123456789012345678901234567890123456789012345678"
validation="SHA1"
decryption="Auto"
/>
(2)SqlServer模式:
1. 要保存在Session中的对象是可序列化的。
2. 如果使用了默认是数据库, 则在客户端配置文件中的数据库链接字符串的用户,需要拥有ASPState和tempdb两个库的dbowner权限.
3. 在SQLServer模式下,session过期是由SQL Agent使用一个注册任务完成的,要确认SQL Agent已经运行。否则无法清理过期的Session数据, 会导致数据库数据一直增加.
4. 如果使用SqlServer模式时, 对于Web场中的各服务器的 ASP.NET 应用程序路径必须是相同的。请在 IIS 配置数据库中对 Web 场中的所有 Web 服务器进行 Web 站点的应用程序路径同步。大小写一定要相同,因为 Web 站点的应用程序路径是区分大小写的。
5.需要让所有机器的MachineKey相同.在Machine.Config中配置:
复制代码 代码如下:
<machineKey
validationKey="1234567890123456789012345678901234567890AAAAAAAAAA"
decryptionKey="123456789012345678901234567890123456789012345678"
validation="SHA1"
decryption="Auto"
/>
(3)Session:
1. 不能直接通过Session服务器在ASP.NET和ASP之间共享Session. 请使用微软提供的解决方案:
2. 在不同的应用程序或一个网站的不同虚拟目录之间无法共享Session
3. Session的过期时间是滑动时间.
4. Session存储.NET自带的值类型性能最优. 存储对象会降低性能.
(4)SessionID:
1.SessionID 还可以保存在URL上, 设置Web.Config文件中的System.Web/sessionState节点的Cookiesless属性即可:
复制代码 代码如下:
<sessionState
cookieless="UseUri"
/>
2. 一般在Session超时或删除之后,SessionID保持不变. 因为Session过期后会在服务器端清除数据, 但是SessionID保存在用户浏览器上, 所以只要浏览器不关闭则HTTP头中的SessionID保持不变.
3.关闭浏览器后再访问, SessionID会不同.
4.每打开一个IE6窗口, SessionID都不同, 在IE6中两个窗口的Session不能共享.
5.FireFox的标签页和新的FireFox窗口, SessionID都相同, 在FF的窗口和标签页上Session能共享.
6.对于包含FrameSet的页面,比如:
复制代码 代码如下:
<frameset cols="25%,50%,25%">
<frame src="https://www.jb51.net/SessionID.aspx">
<frame src="https://www.jb51.net/SessionID.aspx">
<frame src="https://www.jb51.net/SessionID.aspx">
</frameset>
如果后缀名是.htm并且.htm文件没有交给ASP.NET的ISAPI处理, 那么根据服务器速度在每个Frame页面生成不同的SessionID, 再刷新后相同都等于最后一个SessionID.
解决办法是将.htm后缀改成.aspx, 或者将.htm文件交给ASP.NET的ISAPI处理.
(5)Session_End事件:
1. Session_End仅在InProc模式中可用
2. 关闭浏览器,Session_End是不会触发的。HTTP是一种无状态协议,服务器没有办法知道你的浏览器是否已经关闭。
3. 当Session因为时间过期或调用Session.Abandon时,Session_End才会触发.Session.Clear()仅仅是清除数据,但没有删除session。
4. Session_End由一个后台线程触发,使用工作者进程账号运行. 所以程序不会通知发生的错误.
5. 在Session_End访问数据库要考虑权限问题. Session_End是用运行工作者进程(aspnet_wp.exe)的帐号运行的,这个账号可以在machine.config中指定。因此,在Session_End中,如果使用integrity security连接SQL,它将使用工作者进程账号身份连接,这可能会引起登录失败.
6.因为Session_End是有独立线程出发的, 所以在Session_End中无法使用HttpContext对象(Request,Response,Server等对象都在HttpContext中), 即无法使用 Response.Redirect 和Server.Transfer等方法.