【问题标题】:spring session - prevent concurrent modification of sessionspring session - 防止同时修改会话
【发布时间】:2016-12-05 15:26:52
【问题描述】:

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

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

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

非常感谢 乙

【问题讨论】:

    标签: spring-session


    【解决方案1】:

    Spring Session 不使用任何会话锁定机制,因为这会对性能产生非常负面的影响。请注意,您的示例侧重于单个会话,而锁定会影响属于给定会话的所有请求,其中许多请求可以完全安全地同时执行。

    对于您示例中的场景,应采用另一种机制来提供保护。这可能很简单,例如在操作完成之前禁用 UI 上的按钮,从而阻止后续请求,或者使用 CSRF 保护来确保修改服务器端的每个请求。

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

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

    【讨论】:

    • 非常感谢 Vedran。一些评论:禁用按钮不会解决问题,因为用户仍然可以按“F5”或使用多个浏览器窗口。我在任何 SessionRepository 中都没有找到合适的机制来处理我的问题——无论如何,RedisOperationsSessionRepository 肯定不能解决问题。使用 CSRF 保护令牌来检测并发修改是一个非常有趣的想法。我试试看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 2018-03-14
    相关资源
    最近更新 更多