stackoverflow上的第一篇文章,希望得到很好的反馈:)
我目前正在尝试对我们的网站进行负载均衡。我们在带有IIS 6的Windows Server 2003上设置了2个集群NLB。
在测试设置时,我发现有时,我们的会话丢失了。一天半之后,结果如下:
从那时起,在谷歌上搜索会提供更少的信息和可能的解决方案。
据我所知,没有特定的模式导致这个问题。它偶尔会发生一次。
在尝试查找问题时,我发现请求已将asp会话ID cookie发送到服务器,但服务器未将其映射到用户会话。
因此,请求号x是从客户端发送的,其中包含cookie,会话已映射,一切顺利。 请求号x + 1是从客户端发送的,带有cookie,但未找到会话。
这两个请求都是在NLB中的同一台机器上完成的。
这是asp trace.axd的片段:
第一次请求:
请求详细信息 会话ID:j2ffvy45updpc52uhw1mbg55请求类型:GET 请求时间:2008年11月26日下午2:58:06状态代码:200 请求编码:Unicode(UTF-8)响应编码:Unicode(UTF-8)
请求Cookie集合
名称值大小
ASP.NET_SessionId j2ffvy45updpc52uhw1mbg55 42 AID 22 9
响应Cookie集合
名称值大小
标题集
名称值
Cookie ASP.NET_SessionId = j2ffvy45updpc52uhw1mbg55; AID = 22
第二次请求:
请求详细信息
会话ID:请求类型:POST
请求时间:2008年11月26日下午2:58:08状态代码:
请求编码:Unicode(UTF-8)响应编码:
请求Cookie集合
名称值大小
响应Cookie集合
名称值大小
标题集 名称值 Cookie ASP.NET_SessionId = j2ffvy45updpc52uhw1mbg55; AID = 22
正如你在第二个请求中看到的那样,cookie是从客户端发送的,但是asp似乎永远不会在其中添加cookie“Request Cookies Collection”。我认为这就是它找不到会话的原因。
那么为什么cookie没有映射到会话?那是问题吗?问题出在其他地方吗?
随意提出任何澄清。
感谢大家的反馈。
JF
答案 0 :(得分:1)
我终于找到了问题的答案。它的起源是在应用程序代码中(比如99%的程序员第三方工具'错误')。无论如何,我决定发布它以防有人处于类似情况。
此代码是WebServiceRequester类的一部分。创建会话时将Web服务请求者类实例化,并将其保存在会话中。在创建期间,我们初始化成员'm_webServiceURL',并且此成员在会话之后保存。此成员初始化的值取决于本地计算机上的设置。
重要的部分如下: WebServiceRequester类包含WebService对象。 WebService对象无法在会话中保存,它们在asp中不可序列化。该属性具有[NonSerialized]属性。因此,每当我们在页面生命周期中访问第一个对象的'WebService'属性时,我们必须创建一个新属性,并为其分配保存在会话中的url'm_webServiceURL'。 所以你看,新的webservice对象,可能在不同的机器上,意味着每台机器上有不同的设置。
所以这是发生的事情: 框29设置为访问localhost
上的Web服务框30设置为访问Web服务192.168.253.29。
从技术上讲,它们都设置在同一台机器上。但这是一个场景:
登录框29. m_webServiceURL在会话中设置为localhost。
[此处第29栏请求]
NLB平衡将我们带到方框30。 框30加载它的会话,使用localhost创建一个新的webservice对象作为Web服务地址。 框30向错误的Web服务发出请求,导致会话过期异常。
调试期间的一个问题是本地通信没有记录在网络监视器中。
引导我跟踪的是,我们从未在第29条日志跟踪上记录异常,因为它应该有。
感谢大家的建议,非常感谢。
祝你有个美好的一天。 JF
答案 1 :(得分:0)
对您的问题不是一个严格的答案,但您是否尝试使用基于sql server的会话存储? (在MSDN上搜索永久脚本而不是asp.net提供的临时脚本)
我听说过关于可执行会话服务的“坏事”,因此没有使用它。尽管如此,使用基于sql server的解决方案从未出现任何问题。
很抱歉,这不是问题的答案,但它应该(a)修复它,或者(b)显着缩小范围。
答案 2 :(得分:0)
好吧,如果您正在使用visual studio,您至少可以使用MSDE(Visual Studio附带的SQL Server的缩减版本)进行测试......
它可能有助于排除状态服务器问题......
答案 3 :(得分:0)
使用数据库方法有其自身的问题。我认为你应该能够使用你喜欢的方法。
也许this session troubleshooting article会有所帮助?
或“Troubleshooting Session Related Issues in ASP.NET”
或“Troubleshooting Expired ASP.NET Session State and Your Options”
答案 4 :(得分:0)
我会跛脚并重新重复MS SQL Server的提议。安装完全免费的SQL Server Express,包括商业用途,它只有这三个缺点,在这个阶段不应该是你的问题:
答案 5 :(得分:0)
需要考虑以下几点:
如果您要将MSSQL Express用作您的状态数据库,请记住它没有附带SQL Server代理,这意味着后台没有运行任务调度程序并清理过期的会话。我建议定期查找调度程序并运行干净的过期会话存储过程。
祝你好运答案 6 :(得分:0)
不要乱用SQL,而是将测试直接发送到一个IIS节点,看看是否仍然遇到同样的问题。我敢肯定,如果您只进行少量测试,StateServer将不会成为问题。
答案 7 :(得分:0)
尝试通过代码将asp.net_sessionid的域名设置为“.yourdomain.com”。 默认情况下,ASP.net_SessionID cookie域名设置为完整的应用程序路径。所以,这可能是cookie没有旅行的原因之一。
E.g。 Request.Cookies [“ASP.NET_SessionId”]。Domain =“。yourdomain.com”。 记住第一个“。”在域名中很重要。
您可以在AcquireRequestState事件中的HttpModule中执行此操作。