粘性会话和会话复制

Posted

技术标签:

【中文标题】粘性会话和会话复制【英文标题】:Sticky Sessions and Session Replication 【发布时间】:2011-09-16 02:30:49 【问题描述】:

我正在评估在 tomcat 中使用带有会话复制的粘性会话的情况。从我最初的评估来看,我认为如果我们启用会话复制,那么在一个 tomcat 节点中启动的会话将被复制到所有其他 tomcat 节点,因此我们不需要粘性会话来继续会话,并且请求可以被任何节点接收.

但似乎会话复制通常与粘性会话一起使用,否则每当请求转到某个其他节点时都需要更改会话 ID。参考:http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html#Bind_session_after_crash_to_failover_node

如果您必须启用粘性会话,谁能解释会话复制的真正用途是什么?因为那样你将不必要地在每个节点上复制会话,当具有给定会话 id 的请求总是去同一个节点时。这在节点崩溃的情况下可能是有益的,但这种情况不会经常发生,并且仅为此使用会话复制似乎有点过头了。

【问题讨论】:

不是您所问问题的答案,但也许仍然有用:您可以查看 memcached-session-manager (code.google.com/p/memcached-session-manager),它也为非粘性会话提供会话复制。跨度> 由于用户连接的节点可能会宕机,会话复制使其他健康节点能够恢复相同会话。所以不是“如果你必须启用粘性会话,谁能解释会话复制的真正用途是什么?”,我宁愿问:如果你必须会话复制,谁能解释一下粘性会话的真正用途是什么?因为它更有趣……而且我想到的唯一答案是:在这种情况下,粘性会话 only 加快了通信速度,不管有没有它,会话都在那里。 【参考方案1】:

我认为唯一真正的好处是能够不假思索地关闭 Tomcat 实例。这尤其适用于今天的云世界(想想亚马逊 AWS 现货实例),此时节点可以非常频繁地打开和关闭。替代方案是购买一个支持节点耗尽的体面的负载均衡器。但体面的负载均衡器价格昂贵,而且消耗时间很长。

我能想到的另一种情况是购物车(实施不佳),其中物品保存在HttpSession 中,并且关闭将需要用户重新购买它们(这可能会导致销售损失)。

但在大多数情况下,您是对的 - 同时拥有粘性会话和会话复制的好处非常微不足道。

【讨论】:

感谢您的回复。谢谢似乎很好,但我仍然不确定是否需要使用粘性会话启用会话复制,或者是否也可以在没有粘性会话的情况下使用它? 复制可以在没有粘性会话的情况下使用,反之亦然。 但是正如这个链接中提到的...tomcat.apache.org/tomcat-6.0-doc/… ...似乎在没有粘性会话的情况下启用会话复制似乎会导致问题 我看不出文章在哪里说这会导致问题。文章谈到了在这种情况下无关紧要的 mod_jk。【参考方案2】:

只是为了澄清 JBoss 5.X 在“所有”基本配置中使用 mod_jk 的配置问题。在workers.properties 文件中设置粘性会话

 worker.list=loadbalancer

 ... nodes configuration omitted

 worker.loadbalancer.balance_workers=node1,node2
 worker.loadbalancer.sticky_session=True

不会阻止会话复制。为了关闭 JBoss 上的会话复制,我们需要在 $JBOSS_HOME\server\YOUR_NODE_NAME\deploy\cluster\jboss-cache-manager.sar\META-INF\jboss-cache-manager-jboss-beans.xml @987654322 中设置@参数为LOCAL

通常在粘性会话场景中,我们不希望会话复制,因为我们不希望与复制会话所需的大量 I/O 操作相关的额外开销。

事实上,如果使用粘性会话,我们不需要在“全部”配置中运行 JBoss,我们可能会使用“默认”或“标准”配置。

唯一需要做的就是改变$JBOSS_HOME/server/YOUR_NODE_NAME/deploy/jbossweb.sar/server.xml:

<Engine name="jboss.web" defaultHost="localhost" jvmRoute="YOUR_NODE_NAME">

【讨论】:

在你的例子中应该是worker.loadbalancer.sticky_session=false吗?【参考方案3】:

正如 Mindas 之前解释的那样:

当您使用负载平衡时,这意味着您有多个 tomcat 实例,您需要分配负载。

如果您使用没有粘性会话的会话复制:假设您只有一个用户在使用您的网络应用,而您有 3 个 tomcat 实例。该用户向您的应用发送多个请求,然后 负载均衡器会将其中一些请求发送到第一个 tomcat 实例,并将其他一些请求发送到第二个 实例,其他到第三个。 如果您使用的是没有复制的粘性会话: 假设您只有一个用户在使用您的网络应用程序,而您有 3 个 tomcat 实例。该用户向您的应用发送多个请求,然后 负载均衡器会将第一个用户请求发送到三个中的一个 tomcat 实例,以及由此发送的所有其他请求 会话期间的用户将被发送到同一个 tomcat 实例。 在这些请求期间,如果您关闭或重新启动此 Tomcat 实例(使用的tomcat实例)负载均衡器发送 对另一个仍然存在的 tomcat 实例的剩余请求 正在运行,但由于您不使用会话复制,因此实例 接收剩余请求的tomcat没有 用户会话然后对于这个tomcat,用户开始一个会话: 用户失去了他的会话并与网络应用程序断开连接,尽管 网络应用仍在运行。 如果您正在使用带有会话复制的粘性会话: 假设您只有一个用户在使用您的网络应用程序,而您有 3 个 tomcat 实例。该用户向您的应用发送多个请求,然后 负载均衡器会将第一个用户请求发送到三个中的一个 tomcat 实例,以及由此发送的所有其他请求 会话期间的用户将被发送到同一个 tomcat 实例。 在这些请求期间,如果您关闭或重新启动此 Tomcat 实例(使用的tomcat实例)负载均衡器发送 对另一个仍然存在的 tomcat 实例的剩余请求 当您使用会话复制时,正在运行的实例 tomcat 接收剩余的请求有一个用户会话的副本然后 用户继续他的会话:用户继续浏览您的网络 app没有被断开,tomcat实例的关闭 不会影响用户导航。

【讨论】:

这很好理解,我的问题是除了节点崩溃之外它还有其他用途,正如我在问题本身中提到的那样“如果节点崩溃可能会有所帮助”。跨度> 好的,你说的是“节点崩溃”,但你也可能想更改两个节点,或者删除两个节点,或者你想更新你的 Web 应用程序......这样做你不需要不想停止用户会话,您希望他们看不到您的干预。然后使用复制将允许您执行此操作。 因此,当我们进行会话复制时,粘性会话只会加快通信速度,因为无论有没有它,会话都存在。我说的对吗?

以上是关于粘性会话和会话复制的主要内容,如果未能解决你的问题,请参考以下文章

使用粘性会话和 websocket 进行扩展

在 tomcat 实例之间共享会话(不使用粘性会话)

Apache + Tomcat - 粘性会话和负载平衡问题

负载均衡器粘性会话和非常旧的 Web 服务

如何使用 docker swarm 保持粘性会话(会话持久性)?

负载均衡器 cookie 粘性和用于存储用户会话的 ElastiCache 有啥区别?