asp.net,stateserver,NLB,会话丢失

时间:2008-11-26 21:45:52

标签: asp.net session cluster-computing nlb stateserver

stackoverflow上的第一篇文章,希望得到很好的反馈:)

我目前正在尝试对我们的网站进行负载均衡。我们在带有IIS 6的Windows Server 2003上设置了2个集群NLB。

在测试设置时,我发现有时,我们的会话丢失了。一天半之后,结果如下:

  1. 是的,我们的machine.config都有相同的加密/解密密钥。
  2. 是的,iis metabase.xml中的id对于两台机器都是相同的。实际上,除“AdminACL”外,整个文件都是相同的。
  3. 两个Web应用程序都设置为“StateServer”,并且都指向同一台计算机。
  4. 从那时起,在谷歌上搜索会提供更少的信息和可能的解决方案。

    据我所知,没有特定的模式导致这个问题。它偶尔会发生一次。

    在尝试查找问题时,我发现请求已将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

8 个答案:

答案 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,包括商业用途,它只有这三个缺点,在这个阶段不应该是你的问题:

  • 最大4GB大小的数据库
  • 使用最多1个CPU核心
  • 使用最大1GB RAM

答案 5 :(得分:0)

需要考虑以下几点:

  • 您网站上的负载是多少?面对大量并发命中时,State Server可能会崩溃。我们只在我们拥有非常少量用户的情况下使用它(在10年代,主要是后端系统)。每当我们尝试在每天为1000个用户提供服务的网站的生产中使用它时,它都会崩溃,导致会话数据丢失。
  • 在我们管理的其中一个生产环境中,我们使用MSSQL 2005 Express来管理会话,该网站每天有10K +用户,每天有200,000多页。如果会话是必须的并且紧密耦合到您的应用程序中,这是一种推荐的方法。

如果您要将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中执行此操作。