会话变量通常保存在 Web 服务器 RAM 内存中。
在集群中,客户端发出的每个请求都可以由不同的集群节点处理。正确的?!
所以,在这种情况下...
- 会话变量会发生什么?它们不是存储在节点 RAM 内存中吗?
- 如果其他节点没有我的会话变量,或者至少没有我的会话变量,其他节点将如何正确处理我的请求?
- 这个问题是由 Web 服务器(Apache、IIS)还是由语言运行时(PHP、ASP.NET、Ruby、JSP)处理的?
编辑: Classic ASP有什么解决方案吗?
会话变量通常保存在 Web 服务器 RAM 内存中。
在集群中,客户端发出的每个请求都可以由不同的集群节点处理。正确的?!
所以,在这种情况下...
编辑: Classic ASP有什么解决方案吗?
扩展@yogman 的答案。
Memcached真是太棒了!它是一个高性能的分布式对象缓存。
即使我提到分布式,它基本上就像在您的一台备用/空闲服务器上启动一个实例一样简单,您将其配置为 ip、端口和要使用多少内存,然后就完成了。
memcached -d -u www -m 2048 -l 10.0.0.8 -p 11211
(在守护进程模式下运行 memcached,作为用户 www,IP 10.0.0.8 上的 2048 MB (2 GB) RAM,端口为 11211。)
从那时起,您向 memcached 询问数据,如果数据尚未缓存,则从原始源中提取数据并将其存储在 memcached 中。我确定您熟悉缓存基础知识。
在集群环境中,您可以将您的 memcached 链接到集群中并跨节点复制缓存。Memcached 在 Linux、Unix 和 Windows 上运行,在您有空闲 RAM 的任何地方启动它并开始使用您的资源。
memcached 的 API 应该普遍可用。我说应该是因为我只知道 Perl、Java 和 PHP。但我确信,例如在 Python 中,人们也有办法利用它。有一个memcached wiki,以防您需要指针,或者如果我说得太多,请在评论中告诉我。;)
有 3 种方法可以在 ASP.NET 中存储会话状态。第一个是在进程中,变量存储在内存中。第二种是通过将以下内容放入您的 web.config 文件中来使用会话状态服务:
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;user id=sa;password="
cookieless="false"
timeout="20" />
正如您在 stateConnectionString 属性中看到的,会话状态服务可以位于不同的计算机上。
第三种选择是使用集中式 SQL 数据库。为此,您将以下内容放入 web.config 中:
<sessionState
mode="SQLServer"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString=
"data source=SERVERHAME;user id=sa;password="
cookieless="false"
timeout="20"
/>
所有这些选项的更多细节都写在这里:http ://www.ondotnet.com/pub/a/dotnet/2003/03/24/sessionstate.html
获取一台 Linux 机器并设置http://www.danga.com/memcached。与其他方法相比,它的速度是无与伦比的。(例如,cookies、表单隐藏变量、数据库)
使用Hazelcast,您可以使用 Hazelcast 分布式地图在集群中存储和共享会话,或者让 Hazelcast Webapp Manager 为您完成所有工作。请查看文档以获取详细信息。Hazelcast 是用于 Java 的分布式/分区、超级精简和简单、免费的数据分发解决方案。
问候,
-塔利普
与各种事情一样,“这取决于”。
有不同的解决方案和方法。
如前所述,会话状态(数据库、memcached、共享文件系统等)有一个集中存储的概念。
还有集群范围的缓存系统可用,使集群中的所有机器都可以使用本地数据。从概念上讲,它类似于集中式会话状态存储,但此数据不是持久的。相反,它存在于各个节点中,并使用您的提供者提供的某种机制进行复制。
另一种方法是服务器固定。当客户端第一次访问集群时,某种机制(通常是集群前面的负载平衡器)将客户端固定到特定服务器。在典型的客户端生命周期中,该客户端将把所有时间都花在一台机器上。
对于故障转移机制,集群的每台机器都与另一台机器配对,因此任何会话更改都与配对机器共享。如果客户端固定的机器遇到问题,客户端将撞到另一台机器。此时,可能由于 cookie 的原因,新机器发现它不是客户端的原始机器,因此它会 ping 原始机器和配对机器以获取客户端会话数据。
那时,客户端很可能被固定到新机器上。
不同的平台以不同的方式做到这一点,包括根本没有会话状态。
为了实现经典 ASP 的负载平衡,您可以将用户特定的值存储在数据库中,并在 URL 中传递一个引用唯一 ID,如下所示。
在数据库中维护一个会话表,为每条记录生成一个唯一的 id。第一次要存储会话特定数据时,在会话表中生成一条记录并将会话值存储在其中。获取新会话记录的唯一 ID 并重写Web 应用程序中的所有链接,以将唯一 ID 作为查询字符串的一部分发送。
在您需要会话数据的每个后续页面中,使用在查询字符串中传递的唯一 ID 查询会话表。
例子:
假设您的网站有 4 个页面:Login.asp、welcome.asp、taskList.asp、newtask.asp
当用户使用 login.asp 页面登录时,在验证用户后,在会话表中创建一条记录并存储所需的会话特定值(假设此示例中用户的登录日期/时间)。获取新会话记录的唯一 ID(假设唯一 ID 为abcd)。
将您网站中的所有链接附加到以下唯一 ID:
现在,如果您想在上述任何网页中显示用户的登录日期/时间,您只需使用 sessionID 参数(在本例中为abcd)查询会话表并显示给用户。
由于标识会话的唯一值是 URL 的一部分,因此为用户服务的任何 Web 服务器都将能够显示正确的登录日期/时间值。
希望这可以帮助。
在 ASP.NET 中,您可以将会话数据保存到 SQL Server 数据库中,该数据库对集群中的所有 Web 服务器都是通用的。
配置后(在您网站的 web.config 中),框架会为您处理所有持久性,您可以正常访问会话数据。
正如 Will 所说,大多数负载平衡方法将在分发来自同一客户端的即将到来的请求的方式中使用某种粘性,这意味着一个唯一的客户端将访问同一台服务器,除非该实际服务器出现故障。
这最大限度地减少了会话数据分发的需要,这意味着只有在服务器最终发生故障时,客户端才会失去他的会话。根据您的应用程序,这或多或少至关重要。在大多数情况下,这不是一个大问题。
即使是最简单的负载平衡方式(轮询 DNS 查找)也会产生某种粘性,因为大多数浏览器都会缓存实际的查找,因此会继续访问它收到的第一条记录,AFAIK。
通常是运行时负责会话数据,例如在 PHP 中,可以定义自己的会话处理程序,它可以将数据保存到数据库中。默认情况下,PHP 将会话数据存储在文件中,并且可以在 SAN 或同等设备上共享这些文件以共享会话数据。这只是我的一个理论,但从未测试过,因为我们认为丢失会话并不重要并且不希望出现单点故障。