p.campbell Asked: 2009-06-27 11:47:54 +0800 CST2009-06-27 11:47:54 +0800 CST 2009-06-27 11:47:54 +0800 CST 如何跨多个 Web 服务器实现会话粘性? 772 StackOverflow/ServerFault 有多少个 Web 服务器? 如果答案是“不止一个”,那么它是否在 DNS 轮询时实现了会话粘性? domain-name-system web-server 6 个回答 Voted Tommeh 2009-06-27T12:42:47+08:002009-06-27T12:42:47+08:00 大型网站可能会在多台机器上进行“负载平衡”。在许多负载平衡设置中,用户可能会在会话期间访问任何后端机器。因此,存在多种方法来允许多台机器共享用户会话。 选择的方法取决于所采用的负载平衡方式,以及后端存储的可用性/容量: 仅存储在 cookie 中的会话信息:会话信息(不仅仅是会话标识符)存储在用户的 cookie 中。例如,用户的 cookie 可能包含他们购物篮的内容。为防止用户篡改会话数据,可以在 cookie 中提供 HMAC。此方法可能最不适合大多数应用程序: 不需要后端存储 用户不需要每次都打同一台机器,所以可以使用DNS负载均衡 从数据库机器检索会话信息没有延迟(因为它是随 HTTP 请求提供的)。如果您的站点由不同大陆的机器进行负载平衡,则很有用。 会话中可以存储的数据量受到限制(受 4K cookie 大小限制) 如果用户不能看到他们的会话内容,则必须使用加密 必须使用 HMAC(或类似的)来防止用户篡改会话数据 由于会话数据不存储在服务器端,因此开发人员调试起来更加困难 负载均衡器始终将用户定向到同一台机器:许多负载均衡器可能会设置其会话 cookie,指示用户从哪台后端机器发出请求,并在将来将它们定向到该机器。因为用户总是被定向到同一台机器,所以不需要多台机器之间的会话共享。这在某些情况下可能很好: 现有应用程序的会话处理可能无需更改即可感知多台机器 存储会话不需要共享数据库系统(或类似系统),这可能会提高可靠性,但代价是复杂性 一个后端机器宕机了,它会关闭任何在它上面启动的用户会话。 让机器停止服务更加困难。应允许在机器上具有要关闭以进行维护的会话的用户在机器关闭之前完成他们的任务。为了支持这一点,Web 负载均衡器可能具有将请求“排出”到某个后端机器的功能。 共享后端数据库或键/值存储:会话信息存储在后端数据库中,所有 Web 服务器都有权查询和更新。用户的浏览器存储一个包含标识符(如会话 ID)的 cookie,指向会话信息。这可能是三种方法中最干净的方法: 用户永远不需要接触存储的会话信息。 用户不需要每次都打同一台机器,所以可以使用DNS负载均衡 一个缺点是可以放置在任何后端存储系统上的瓶颈。 会话信息可能会过期并始终备份。 总体而言,大多数动态 Web 应用程序执行多个数据库查询或键/值存储请求,因此数据库或键/值存储是会话数据的逻辑存储位置。 zombat 2009-06-27T11:52:54+08:002009-06-27T11:52:54+08:00 如果您的问题是如何跨多个前端 Web 服务器维护会话,那么答案通常是使用集中式数据库。您无需依赖 Web 服务器实例来跟踪本地文件系统上的会话文件,而是将会话 ID 和数据写入中央数据库,然后所有 Web 服务器将从那里检索数据。 Tristan 2013-04-26T06:08:51+08:002013-04-26T06:08:51+08:00 使用 nemcached 似乎是一个很好的解决方案,不像@David Pashley 提到的那样 这意味着拥有一个由所有服务器共享的远程 memcached 实例,并使用提供自己的会话处理程序的 memcache PECL 扩展。 只需要更改php配置中的两个参数! 这是一个很好的教程http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/ ongle 2009-06-27T11:53:27+08:002009-06-27T11:53:27+08:00 IIRC,在 DotNetRocks #440 他们说一个服务器周期。不知道是不是还是这样。 编辑:实际上是Hanselminutes #134。对不起。 chris 2009-06-27T12:07:31+08:002009-06-27T12:07:31+08:00 你可以设置一个cookie。 您可以计算远程 IP 的哈希值(最简单的,奇数远程主机到服务器 A,偶数主机到服务器 B)。 如果您使用的是 ssl 隧道,看起来您也可以通过一些保留在源系统中的值来做到这一点。 通常,上述每种机制都需要“反向代理”服务器或某种负载平衡器。该负载均衡器接受流量,然后根据上述标准之一将其定向到最初具有会话的任何服务器。 不过,我不确定您所说的“DNS轮询”是什么意思 Kristaps 2009-06-27T13:39:51+08:002009-06-27T13:39:51+08:00 a) 您可以将会话信息存储在用户 cookie 中。请参阅无状态强化 cookie,它在服务器端不存储任何数据,但保留会话状态http://www.cl.cam.ac.uk/~sjm217/papers/protocols08cookies.pdf。b)您可以将会话后端存储更改为数据库或 memcached。为了消除单点故障,您可以设置数据库复制或多个 memcached 节点。请注意,在这种设置中建议使用 memcached,其中在会话中丢失用户状态并不是大错误并且不会让他非常不高兴。对于保留状态至关重要的情况,请使用数据库。PHP、Django 和 Rails 都允许开发人员编写自定义会话后端。
大型网站可能会在多台机器上进行“负载平衡”。在许多负载平衡设置中,用户可能会在会话期间访问任何后端机器。因此,存在多种方法来允许多台机器共享用户会话。
选择的方法取决于所采用的负载平衡方式,以及后端存储的可用性/容量:
仅存储在 cookie 中的会话信息:会话信息(不仅仅是会话标识符)存储在用户的 cookie 中。例如,用户的 cookie 可能包含他们购物篮的内容。为防止用户篡改会话数据,可以在 cookie 中提供 HMAC。此方法可能最不适合大多数应用程序:
负载均衡器始终将用户定向到同一台机器:许多负载均衡器可能会设置其会话 cookie,指示用户从哪台后端机器发出请求,并在将来将它们定向到该机器。因为用户总是被定向到同一台机器,所以不需要多台机器之间的会话共享。这在某些情况下可能很好:
共享后端数据库或键/值存储:会话信息存储在后端数据库中,所有 Web 服务器都有权查询和更新。用户的浏览器存储一个包含标识符(如会话 ID)的 cookie,指向会话信息。这可能是三种方法中最干净的方法:
总体而言,大多数动态 Web 应用程序执行多个数据库查询或键/值存储请求,因此数据库或键/值存储是会话数据的逻辑存储位置。
如果您的问题是如何跨多个前端 Web 服务器维护会话,那么答案通常是使用集中式数据库。您无需依赖 Web 服务器实例来跟踪本地文件系统上的会话文件,而是将会话 ID 和数据写入中央数据库,然后所有 Web 服务器将从那里检索数据。
使用 nemcached 似乎是一个很好的解决方案,不像@David Pashley 提到的那样
这意味着拥有一个由所有服务器共享的远程 memcached 实例,并使用提供自己的会话处理程序的 memcache PECL 扩展。
只需要更改php配置中的两个参数!
这是一个很好的教程http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
IIRC,在 DotNetRocks #440 他们说一个服务器周期。不知道是不是还是这样。
编辑:实际上是Hanselminutes #134。对不起。
你可以设置一个cookie。
您可以计算远程 IP 的哈希值(最简单的,奇数远程主机到服务器 A,偶数主机到服务器 B)。
如果您使用的是 ssl 隧道,看起来您也可以通过一些保留在源系统中的值来做到这一点。
通常,上述每种机制都需要“反向代理”服务器或某种负载平衡器。该负载均衡器接受流量,然后根据上述标准之一将其定向到最初具有会话的任何服务器。
不过,我不确定您所说的“DNS轮询”是什么意思
a) 您可以将会话信息存储在用户 cookie 中。请参阅无状态强化 cookie,它在服务器端不存储任何数据,但保留会话状态http://www.cl.cam.ac.uk/~sjm217/papers/protocols08cookies.pdf。b)您可以将会话后端存储更改为数据库或 memcached。为了消除单点故障,您可以设置数据库复制或多个 memcached 节点。请注意,在这种设置中建议使用 memcached,其中在会话中丢失用户状态并不是大错误并且不会让他非常不高兴。对于保留状态至关重要的情况,请使用数据库。PHP、Django 和 Rails 都允许开发人员编写自定义会话后端。