2

关于stackoverflow的第一篇文章,希望有很好的反馈:)

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

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

  1. 是的,我们的 machine.config 都具有相同的加密/解密密钥。
  2. 是的,两台机器的 iis metabase.xml 中的 id 相同。实际上,整个文件都是一样的,除了“AdminACL”。
  3. 两个 Web 应用程序都设置了“StateServer”,并且都指向同一台机器。

从那时起,在谷歌上搜索提供的信息和可能的解决方案就更少了。

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

在尝试查找问题时,我看到一个请求将 asp session id cookie 发送到服务器,但服务器没有将其映射到用户会话。

于是客户端发出了请求号x,带有cookie,session被映射,一切顺利。请求号 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; 援助=22

第二个要求:

请求详细信息会话 ID:请求类型:POST 请求时间:2008 年 11 月 26 日下午 2:58:08 状态代码:
请求编码:Unicode (UTF-8) 响应编码:

请求 Cookie 收集

名称 值 大小

响应 Cookie 集合

名称 值 大小

标头集合名称值 Cookie ASP.NET_SessionId=j2ffvy45updpc52uhw1mbg55; 援助=22

正如您在第二个请求中看到的,cookie 是从客户端发送的,但 asp 似乎从未将 cookie 添加到它的“请求 cookie 集合”中。我认为这就是它找不到会话的原因。

那么为什么cookie没有映射到会话呢?那是问题吗?问题在其他地方吗?

随时询问任何澄清。

谢谢大家的反馈。

杰夫

4

8 回答 8

1

我终于找到了我的问题的答案。它的起源是在应用程序代码中(就像 99% 的程序员的 3rd 方工具“错误”)。无论如何,我决定发布它以防有人处于类似情况。

此代码是 WebServiceRequester 类的一部分。Web 服务请求者类在创建会话时被实例化并保存在会话中。在创建过程中,我们初始化了成员'm_webServiceURL',之后这个成员保存在会话中。此成员初始化的值取决于本地计算机上的设置。

重要的部分如下: WebServiceRequester 类包含一个 WebService 对象。WebService 对象不能保存在会话中,它们在 asp 中不可序列化。该属性具有 [NonSerialized] 属性。因此,每次我们在页面生命周期中第一次访问对象的“We​​bService”属性时,我们都必须创建一个新属性,并为其分配保存在会话中的 url“m_webServiceURL”。所以你看,新的 webservice 对象,可能在不同的机器上,这意味着每台机器上的不同设置。

所以这就是发生的事情:框 29 被设置为在 localhost 访问 Web 服务

框 30 设置为以 192.168.253.29 访问 Web 服务。

从技术上讲,它们都设置在同一台机器上。但这里有一个场景:

在框 29 上登录。m_webServiceURL 在会话中设置为 localhost。

[关于方框 29 的一些要求]

NLB 平衡将我们带到框 30。框 30 加载它的会话,以 localhost 作为 Web 服务地址创建一个新的 Web 服务对象。框 30 向错误的 Web 服务发出请求,导致 Session Expired 异常。

调试过程中的问题之一是本地通信没有被网络监视器记录下来。

在跟踪中引导我的是,我们从来没有在框 29 日志跟踪中记录异常,因为它应该有。

谢谢大家的建议,真的很感激。

祝你有美好的一天。杰夫

于 2008-12-03T20:43:28.857 回答
0

严格来说不是您问题的答案,但是您是否尝试过使用基于 sql server 的会话存储?(在 MSDN 上搜索永久脚本而不是 asp.net 提供的临时脚本)

我听说过关于可执行会话服务的“坏事”,因此没有使用它。不过,使用基于 sql server 的解决方案从来没有遇到过任何问题。

抱歉,严格来说,这不是您问题的答案,但它应该 (a) 修复它,或 (b) 显着缩小范围。

于 2008-11-26T21:50:45.943 回答
0

好吧,如果您使用的是 Visual Studio,您至少可以使用 MSDE(Visual Studio 附带的 SQL Server 的精简版)对其进行测试...

它可能有助于排除状态服务器问题......

于 2008-11-26T22:03:01.193 回答
0

使用数据库方法有其自身的问题。我认为您应该能够使用您喜欢的方法。

也许这篇会话故障排除文章会有所帮助?

或“在 ASP.NET 中解决与会话相关的问题

或“对过期的 ASP.NET 会话状态和您的选项进行故障排除

于 2008-11-26T22:31:11.730 回答
0

我会跛脚并重新迭代MS SQL Server的提议。安装完全免费的 SQL Server Express,包括商业用途,它只有这 3 个缺点,在这个阶段对你来说应该不是问题:

  • 最大 4GB 大小的数据库
  • 最多使用 1 个 CPU 内核
  • 使用的最大 1GB RAM
于 2008-11-27T00:47:15.167 回答
0

需要考虑的几点:

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

如果您将使用 MSSQL Express 作为您的状态数据库,请记住它不附带 SQL Server 代理,这意味着没有任务调度程序在后台运行并清理您过期的会话。我建议找到一个调度程序并定期运行干净的过期会话存储过程。

祝你好运

于 2008-11-28T03:18:07.360 回答
0

不要乱用 SQL,而是将测试直接发送到您的 IIS 节点之一,看看您是否仍然遇到同样的问题。我敢肯定,如果您只进行少量测试 StateServer 不会是问题。

于 2008-11-28T05:17:55.307 回答
0

尝试通过代码将asp.net_sessionid的域名设置为“.yourdomain.com”。默认情况下,ASP.net_SessionID cookie 域名设置为完整的应用程序路径。因此,这可能是 cookie 不旅行的原因之一。

例如 Request.Cookies["ASP.NET_SessionId"].Domain = ".yourdomain.com"。记住第一个“。” 在域名中很重要。

您可以在 AcquireRequestState 事件的 HttpModule 中执行此操作。

于 2008-11-28T06:05:16.257 回答