2016-12-05 112 views
0

在运行应用程序的多个负载平衡实例时,是否可以防止会话的并发修改?春季会话 - 防止会话的并发修改

上下文:多个tomcat,全部运行相同的应用程序。该应用程序使用spring会话将会话存储在redis集群中。负载均衡器将传入的请求分发给其中一个tomcats(非粘性)。用户点击按钮,tomcat 1非常缓慢地处理请求(性能问题或其他)。用户再次点击按钮,tomcat 2更快并回复成功。用户转到下一页。 Tomcat 1完成第一个请求并覆盖会话 - 所有正在进行的页面的数据都将丢失。

解决方案是锁定会话。从而tomcat 2可以检测到并发修改并回复一个错误(比获得不一致的状态好得多)。

THX很多 AB

回答

0

春季会议中不使用任何会话锁定机制,因为这将有性能非常不利的影响。请注意,您的示例关注于单个对话,而锁会影响属于给定会话的所有请求,其中许多对于并发执行都非常安全。

对于您的示例中的场景,应采用另一种机制来提供保护。这可能是一些简单的像禁用按钮UI,直到动作完成,因此防止后续请求,或使用CSRF保护,这将确保每一个修改服务器端的请求。

另请注意,Spring会话提供的大部分会话存储库实现都提供了优化写操作,其目标是减少竞争条件 - 这包括在保存之前检查会话以进行修改,以及在某些情况下优化的保存操作只写入已更改的属性。这是由于不同性质的底层数据存储处理每个会话存储库不同的,因此您在您所选择的存储库中的SessionRepository#save实施。

也许有点相关,Spring会话从版本1.3.0(即撰写本文的时候,在发布候选阶段)开始提供了与Spring Security并发会话控制的集成。详情请查看reference manual

+0

Thx很多Vedran。一些言论: 禁用按钮将不会解决问题,因为用户仍然可以点击“F5”,或者使用多个浏览器窗口。 我没有找到一个合适的机制来处理任何SessionRepository我的问题 - 反正RedisOperationsSessionRepository绝对不解决问题。 使用CSRF保护标记是检测并发修改的一个非常有趣的想法。我会试一试。 – user7252656