解决WEB场中网络负载均衡后产生大Session丢失的问题
在WEB场中,动态网页往往会因为几台主机做了负载而产生SESSION丢失的问题,网上也有很多的介绍,我这里只将我经历的过程给大家分享一下:
系统要运行在负载平衡的 Web场环境中,而系统配置文件web.config中的Session状态却设置为InProc(即在本地存储会话状态),导至在用户访问量大时,Session常经超时的情况。引起这个现象的原因主要是因为用户通过负载平衡IP来访问WEB应用系统,某段时候在某台服务器保存了Session的会话状态,但在其它的WEB前端服务器中却没有保存Session的会话状态,而随着并发量的增大,负载平衡会当作路由随时访问空闲的服务器,结果空闲的服务器并没有之前保存的Session会话状态。
解决办法:
1.当您在负载平衡的 Web 场环境中运行 ASP.NET Web 应用程序时,一定要使用 SqlServer 或StateServer会话状态模式,在项目中我们基于性能考虑并没有选择SqlServer模式来存储Session状态,而是选择一台SessionStateServer服务器来用户的Session会话状态。我们要在系统配置文件web.config中设置如下:
<sessionState mode="StateServer" cookieless="false"timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400"/>
这里的红字体的IP一定要是同域的一台机器,在这台机器上进行第二步的操作,同时将其注册表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameter
s\AllowRemoteConnection的键值改为1,然后重启本机的ASP.NET State Service服务
还要添加一项
<machineKeyvalidationKey="78AE3850338BFADCE59D8DDF
如何生成machineKey?
按照MSDN的标准说法:“对密钥进行配置,以便将其用于对 Forms 身份验证Cookie数据和视图状态数据进行加密和解密,并将其用于对进程外会话状态标识进行验证。”也就是说Asp.Net的很多加密,都是依赖于machineKey里面的值,例如Forms身份验证Cookie、ViewState的加密。默认情况下,Asp.Net的配置是自己动态生成,如果单台服务器当然没问题,但是如果多台服务器负载均衡,machineKey还采用动态生成的方式,每台服务器上的machinekey值不一致,就导致加密出来的结果也不一致,不能共享验证和ViewState,所以对于多台服务器负载均衡的情况,一定要在每台站点配置相同的machineKey。
machineKey生成的算法:
validationKey = CreateKey(20);
decryptionKey = CreateKey(24);
附参考的matchineKey配置:
<?xml version="1.0"?>
<configuration>
<system.web>
</configuration>
2. 我们同时还要在SessionStateServer 服务器中启动ASP.NET StateService服务,具体设置:控制面板>>管理工具>>服务>>ASP.NETState Service,把它设为自动启动即可。
3. 每台前端WEB服务的Microsoft“Internet 信息服务”(IIS)设置
补充一些相关资料:
PRB: Session Variables Are Lost If You Use FRAMESET in InternetExplorer 6.0
/kb/323752/EN-US/#
PRB: Session Data Is Lost When You Use ASP.NET InProc SessionState Mode
/?id=324772
PRB:如果您使用 SqlServer 或 StateServer 会话模式 Web 场中会丢失会话状态
/default.aspx?scid=kb;zh-cn;325056
ASP.NET Session State FAQ
/articles/20021016.asp