折腾了好久,趁脑子还清醒记录一下,以免大家掉坑
环境:
两个应用服务器windowsserver2016,一台数据库服务器windowsserver2012
两个应用服务器做了网络负载均衡,导致session一直掉,通过搜索找到此篇参考
步骤一:
https://blog.csdn.net/aidang8943/article/details/102435830
再次感谢原作者,抄写方案如下
在基于NLB(网络负载平衡)环境下的ASP.NET Web应用程序开发,我们需要将Session存储在数据库中供多个Web应用程序调用,以下为配置方法及注意事项。
1.创建用于存储ASP.NET Session的数据库(远程、本地皆可,使用数据库用户身份认证)
在Windows\Microsoft.NET\Framework/V2.0.50727目录下使用如下命令:
aspnet_regsql.exe -S 〈SQL Server IP> -U 〈User Name> -P 〈Password> -E -ssadd -sstype c -d 〈Database Name>
命令执行后就会成功建立起用于存储ASP.NET Session变量的数据库了。
其实这个exe程序有可视化的操作页面
2.Web.Config文件配置项
我们需要在ASP.NET Web应用程序中的Web.Config文件修改sessionState配置项以使Session状态数据库生效。
配置节点如下,,在system.web节点下:
<sessionState mode="SQLServer"
sqlConnectionString="server=<Server IP>;database=<Database Name>;uid=<User Name>;pwd=<Password>;"
allowCustomSqlDatabase="True"
cookieless="false"
timeout="20" />
两个应用服务器都要配置sessionState
步骤二:
配置完成后,访问,提示错误
为了方便大家搜索到,我打一下几个关键字:sql服务器上未安装asp.net2.0版会话状态,或者asp.net不具有运行dbo.tempGetVersion存储过程的权限。
到这就要去数据库服务上配置了,我又安装了一下asp.net4.5,但还是不行,继续找资料,发现还要在数据库的服务器上 执行一下这个命令:
c:\>Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe -ssadd -sstype c -d GFDataYD -E
这样cmd命令窗体就会提示你去配置sessionstate了
步骤三:
执行完,不报错了,但是session还是会掉,查看数据库发现session信息已经保存在数据库了,原因是我们两个应用会有不同的appname,所以在数据库的存储过程[dbo].[TempGetAppID]里,我们要注释掉关于appname的判断
GO
/****** Object: StoredProcedure [dbo].[TempGetAppID] Script Date: 2020/6/2 15:14:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[TempGetAppID]
@appName tAppName,
@appId int OUTPUT
AS
SET @appName = LOWER(@appName)
SET @appId = NULL
SELECT @appId = AppId
FROM [GFDataYD].dbo.ASPStateTempApplications
--WHERE AppName = @appName
IF @appId IS NULL BEGIN
BEGIN TRAN
SELECT @appId = AppId
FROM [GFDataYD].dbo.ASPStateTempApplications WITH (TABLOCKX)
--WHERE AppName = @appName
IF @appId IS NULL
BEGIN
EXEC GetHashCode @appName, @appId OUTPUT
INSERT [GFDataYD].dbo.ASPStateTempApplications
VALUES
(@appId, @appName)
IF @@ERROR = 2627
BEGIN
DECLARE @dupApp tAppName
SELECT @dupApp = RTRIM(AppName)
FROM [GFDataYD].dbo.ASPStateTempApplications
WHERE AppId = @appId
RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.',
18, 1, @appName, @dupApp)
END
END
COMMIT
END
RETURN 0
步骤四:
到这发现session状态还是掉,再搜索,又发现了csdn的一篇文章:
https://www.cnblogs.com/ryhan/p/3748976.html 原文章写得是作者自己解决问题的过程,大家不想看的继续看我的就行了
其实就是需要配置一下machineKey,session保存在数据库时,会根据这个判断,我们把两个应用服务器的webconfig里system.web节点下都加上这个
<
machineKey
validationKey="3FF1E929BC0534950B0920A7B59FA698BD02DFE8" decryptionKey="280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77" decryption="3DES" validation="SHA1"/>
OK。齐活!
再次感谢上面两篇文章作者