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

Posted

技术标签:

【中文标题】在 tomcat 实例之间共享会话(不使用粘性会话)【英文标题】:Share Sessions between tomcat instances (without using Sticky Sessions) 【发布时间】:2011-06-01 12:12:33 【问题描述】:

我将拥有 3 个 Tomcat 服务器和一个负载均衡器,它可以在不使用“sticky sessions”的情况下分派请求。 我想在服务器之间共享会话的数据,我正在考虑将它们保存在数据库中。我想使用memcached 作为我的数据库前面的一个层,以更快地处理请求并提供给don't put my db under heavy load。 我正在考虑提供我的自定义 tomcat 管理器,该管理器在将会话数据获取/持久化到数据库之前使用 memcached,因为目前我没有看到一种透明的方式(这意味着我必须在如果我切换到另一个应用服务器)。 这是一个好的解决方案还是您看到了更好的方法?

【问题讨论】:

这可能对github.com/rover886/tomcat-pysession-server有帮助 @Amogh 我认为现在spring.io/projects/spring-session 也为 2010 年的这个问题提供了一个很好的透明解决方案:) 【参考方案1】:

在数据库中持久化会话会限制您的可扩展性。如果可扩展性对您来说不是那么重要,那么(db + memcached)是一种有效的方法。

使用非粘性会话时需要记住的一件事是并发请求:例如,当您有ajax 请求(并行/并发执行)它们将由不同的 tomcat 提供服务(由于非粘性),因此同时访问会话。只要您有可能修改会话的并发请求,您就需要实现某种同步/会话锁定。

也许您对此感兴趣:我创建memcached-session-manager 的目标是实现最佳性能和无限可扩展性。它可以与任何与 memcached 兼容的后端(例如 memcachedb、membase 等或只是 memcached)一起使用。 虽然它最初是为粘性会话方法创建的,但已经有一个 branch for nonsticky-sessions 现有和一个 sample app 显示它是如何工作的。 现在有一个thread on the mailing list on further improvements for nonsticky-sessions(处理并发请求并防止单点故障)。

【讨论】:

我只想在这里放一个注释,我刚刚发布了具有非粘性会话支持(以及对 tomcat7 的支持)的 memcached-session-manager。关于非粘性会话的一些详细信息的公告:groups.google.com/group/memcached-session-manager/t/… 关于 ajax 请求的观点非常好。在同一流程中,可能有多个请求到服务器。 @MartinGrotzke 也许这可以帮助github.com/rover886/tomcat-pysession-server【参考方案2】:

将您的会话状态存储在应用服务器(在您的情况下为 Tomcat)之外,是大型网站的一种非常常见且推荐的配置。这通常是为了追求一种称为Shared Nothing 的架构风格。

您可以将您的状态存储在几个不同的地方:db、memcached、商业复制缓存等。它们都适用于不同的权衡组合。就个人而言,我在使用 memcached 方面取得了巨大的成功。 Memcached 非常快速和稳定。

一般来说,我选择简单并使用 N>1 的内存缓存服务器,例如 2。当用户登录时,应用服务器会掷硬币来决定哪个服务器存储用户状态。发送到浏览器的 cookie 包含信息,用于知道从那时起路由到哪个 memcache 服务器。来自浏览器的后续请求在每个请求上从相应的内存缓存服务器获取状态。如果 memcache 服务器出现故障,用户将不得不再次登录,因为应用服务器会重新选择新服务器,但这种情况极为罕见。

【讨论】:

【参考方案3】:

我们在我们的应用程序(Weblogic,但这没关系)中做了类似的事情,我们在浏览器中存储了一个唯一的会话密钥作为 cookie。然后,该密钥将在每次请求时用于从数据库中恢复相关的会话数据。

使用这个原则,我们总是可以使用负载平衡器切换到另一台服务器,而用户不会注意到任何事情。除此之外,我们几乎不会在用户会话中存储任何相关内容,并且在浏览器中使用大量隐藏字段(负载均衡器支持 URL 加密和表单值保护,所以我们是安全的......) .

【讨论】:

@Lucas Eder 我们有类似的设置,不同的是我们使用 Memcached 进行会话存储。 对于某些应用程序“无关紧要”(即会话数据可能不被视为对经过身份验证的用户敏感),但原则上来回传送“会话”数据 - 是否作为“隐藏”字段(当然,html 页面上没有任何字段对用户真正隐藏)或为此目的而制作的 cookie - 是不好的做法。除非应用程序的客户端需要此数据,否则不应将其暴露给浏览器。 @DanFarrell:隐藏字段不是敏感数据,并且表单值保护使其不会被调整。因此,从安全角度来看,我看不出这将是多么糟糕的做法。当然,有很多数据传输开销......【参考方案4】:

我认为Terracotta Web Sessions 是您想要的。

【讨论】:

以上是关于在 tomcat 实例之间共享会话(不使用粘性会话)的主要内容,如果未能解决你的问题,请参考以下文章

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

无法在 AWS 中获得粘性会话?

有啥方法可以在tomcat中的不同应用程序之间共享会话状态?

在 Tomcat 中的上下文之间共享会话数据

为 Apache/Tomcat 负载平衡启用粘性会话模式

ip_hash(不推荐使用) 会话粘性问题分析 Cookie 的 Session Sticky