如何在多个Web服务器之间实现会话粘性?


23

StackOverflow / ServerFault有多少台Web服务器?

如果答案是“不止一个”,那么它在DNS轮询时是否达到了会话粘性


不是真的,但是如果用不同的措词,可能会引起一个有趣的问题。

你应该改一下这个问题。将标题更改为“如何在多个Web服务器上实现会话粘性?” 或类似的东西
威廉·布伦德尔

您能帮我个忙给我看看正确的短语吗?

1
拥有多个服务器的假设意味着粘性会话-这真是令人讨厌-使我感到痛苦。
womble

Answers:


42

大型网站可能会在多台计算机之间实现“负载平衡”。在许多负载平衡设置中,用户可能在会话期间访问任何后端计算机。因此,存在许多方法可以允许许多计算机共享用户会话。

选择的方法将取决于所采用的负载平衡的方式以及后端存储的可用性/容量:

会话信息仅存储在cookie中:会话信息(而不仅仅是会话标识符)存储在用户的cookie中。例如,用户的cookie可能包含其购物篮中的内容。为了防止用户篡改会话数据,可以将HMAC与cookie一起提供。此方法可能最不适合大多数应用程序:

  • 无需后端存储
  • 用户无需每次都使用同一台计算机,因此可以使用DNS负载平衡
  • 从数据库计算机检索会话信息没有任何等待时间(因为HTTP请求提供了该信息)。如果您的站点由不同大陆的计算机进行负载平衡,则很有用。
  • 会话中可以存储的数据量受到限制(受4K Cookie大小限制)
  • 如果用户不应该看到其会话的内容,则必须使用加密
  • 必须使用HMAC(或类似方法)来防止用户篡改会话数据
  • 由于会话数据未存储在服务器端,因此开发人员更难以调试

负载平衡器始终将用户定向到同一台计算机:许多负载平衡器可以设置自己的会话cookie,以指示用户从哪个后端计算机发出请求,并在将来将其定向到该计算机。由于用户始终被定向到同一台计算机,因此不需要在多台计算机之间共享会话。在某些情况下这可能会很好:

  • 可能无需更改现有应用程序的会话处理就可以识别多台计算机
  • 不需要使用共享数据库系统(或类似系统)来存储会话,这可能会提高可靠性,但会增加复杂性
  • 发生故障的后端计算机将关闭与此上启动的所有用户会话。
  • 使机器停止运行更加困难。在关闭计算机之前,应允许在计算机上进行会话以进行维护的用户完成其任务。为此,Web负载平衡器可能具有将请求“排放”到特定后端计算机的功能。

共享的后端数据库或键/值存储:会话信息存储在后端数据库中,所有Web服务器都可以访问该数据库来查询和更新。用户的浏览器存储一个cookie,其中包含指向会话信息的标识符(例如会话ID)。这可能是三种方法中最干净的方法:

  • 用户永远不需要暴露于存储的会话信息。
  • 用户无需每次都使用同一台计算机,因此可以使用DNS负载平衡
  • 一个缺点是无论采用哪种后端存储系统,瓶颈都可能摆在瓶颈上。
  • 会话信息可能已过期并得到一致备份。

总体而言,大多数动态Web应用程序执行许多数据库查询或键/值存储请求,因此数据库或键/值存储是会话数据的逻辑存储位置。


2
+1相当全面的答案,不让我写。:)就数据库存储而言,关系数据库可能是错误的事情。像持久性memcached分支之一一样更好。memcachedb可能合适。您还错过了在服务器之间复制会话信息的操作。这不是最好的方法,但是tomcat之类的方法可以做到,因此值得记录。
David Pashley 2009年

Google,Twitter或Facebook使用哪种方法?
Dannyboy 2014年

1
不确定Google,Twitter或Facebook,但Redis非常适合会话存储。基本上是David Pashley在2009年Redis诞生之初就推荐的“持久性内存缓存”。
本R

4

如果您的问题是如何在多个前端Web服务器之间维护会话,那么答案通常是使用集中式数据库。无需依赖Web服务器实例来跟踪本地文件系统上的会话文件,而是将会话ID和数据写入中央数据库,所有Web服务器都将从那里检索数据。


+1代表集中式数据库。只是为了稍微扩展/简化该想法。如果您在用户的PC上设置了具有唯一性的Cookie(例如全局用户ID),则可以将该GUID存储在数据库中。客户端连接到什么服务器都没有关系,只要它们具有GUID / cookie,您就可以在数据库中查找它们并相应地跟踪会话。
KPWINC

2
将会话存储在关系数据库中总是一个坏主意。您不应该使用数据库来存储瞬态数据。
David Pashley 2009年


0

IIRC,在DotNetRocks#440中,他们说一个服务器周期。不知道情况是否仍然如此。

编辑:实际上是Hanselminutes#134。抱歉。


0

您可以设置一个cookie。

您可以计算远程IP的哈希值(最简单的方法是,奇数编号的远程主机转到服务器A,偶数编号的主机转到服务器B)。

看起来,如果您使用的是ssl隧道,也可以通过源系统中保留的某些值来执行此操作。

通常,上述每种机制都需要“反向代理”服务器或某种负载均衡器。该负载平衡器将接受流量,然后根据上述条件之一将其定向到最初拥有会话的任何服务器。

不过,我不确定您所说的“ DNS轮询”是什么意思


0

a)您可以将会话信息存储在用户cookie中。请参阅无状态的强化cookie,该cookie不会在服务器端存储任何数据,但会保留会话状态http://www.cl.cam.ac.uk/~sjm217/papers/protocols08cookies.pdf。b)您可以将会话后端存储更改为数据库或内存缓存。为了消除单点故障,您可以设置数据库复制或多个内存缓存节点。请注意,在此类设置中建议使用memcached,在这种设置中,在会话中丢失用户状态不是很大的错误,并且不会使他感到非常不快。对于保持状态至关重要的情况,请使用数据库。PHP,Django和Rails都允许开发人员编写自定义会话后端。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.