我想在这些服务器之间共享session数据,并打算将它们持久化到数据库中。我想在我的数据库前面使用memcached作为缓存层,以便更快地提供服务并减轻DB负担。
我在考虑提供我的定制化Tomcat Manager,在获取/持久化session数据到DB之前使用memcached。因为目前我没有看到透明处理的方法(如果我切换到另一个应用服务器,就意味着我必须再次管理它)。
这是一个好的解决方案吗?还是你认为有更好的方法?
将会话持久化在数据库中会限制可扩展性。如果可扩展性对您不是那么重要,这种(db + memcached)方法是有效的。
使用非粘性会话时需要记住一件事情:当您有例如Ajax请求(并行/同时执行)时,它们将由不同的Tomcat提供服务(由于非粘性),因此同时访问会话。只要您有可能修改会话的并发请求,就需要实现某种形式的同步/会话锁定。
也许这对您很有兴趣:我创建了memcached-session-manager,旨在实现最佳性能和无限可扩展性。它可以与任何兼容Memcached的后端一起使用(例如Memcachedb、Membase等或仅Memcached)。虽然它最初是为粘性会话方法创建的,但已经存在一个分支用于非粘性会话,以及一个示例应用程序显示如何处理/它的工作方式。现在有一个邮件列表上的线程,讨论进一步改进非粘性会话(处理并发请求和防止单点故障)。
在大规模网站中,将会话状态存储在应用程序服务器(在您的情况下为Tomcat)之外是一种常见且推荐的配置。通常这是出于追求所谓Shared Nothing架构风格而进行的。
您可以将状态存储在多个不同的位置:数据库、内存缓存、商业复制缓存等等。它们都使用不同的权衡组合。个人而言,我使用过memcached并取得了巨大的成功。Memcached非常快速和稳定。
通常,我选择简单性并使用N个Memcache服务器,其中N>1,例如2。当用户登录时,应用程序服务器会掷硬币以决定哪个服务器存储用户状态。发送到浏览器的Cookie包括有关从那时起路由到哪个Memcache服务器的信息。浏览器发出的后续请求会从适当的Memcache服务器获取状态。如果一个Memcache服务器失败,那么用户将不得不重新登录,因为应用程序服务器会重新选择一个新的服务器,但这种情况极为罕见。
在我们的应用程序(Weblogic,但这并不重要)中,我们会执行类似的操作,即将唯一的会话密钥存储为浏览器中的cookie。每个请求都将使用该密钥从数据库中恢复相关的会话数据。
利用这个原理,我们可以随时使用负载均衡器切换到另一个服务器,而用户不会注意到任何事情。除此之外,我们几乎不会在用户的会话中存储任何相关内容,并且使用了很多隐藏字段来处理浏览器中的信息(负载均衡器支持URL加密和表单值保护,因此我们很安全...)。