【问题标题】:Spring's WebUtils.getSessionMutex(javax.servlet.http.HttpSession) and HttpSessionMutexListener still relevantSpring 的 WebUtils.getSessionMutex(javax.servlet.http.HttpSession) 和 HttpSessionMutexListener 仍然相关
【发布时间】:2012-01-14 12:50:58
【问题描述】:

我想知道 Spring 框架的 HttpSessionMutexListener 侦听器是否仍然适用于当今的应用程序服务器/Web 容器(比如 Tomcat 6 或 Tomcat 7 等 2.5+ servlet 规范服务器),用于在集群环境中锁定会话对象(即在不同的 JVM 之间),还是它们只解决了 2.3(或以前)servlet 规范容器的集群环境中的并发问题,现在没有必要了?

【问题讨论】:

    标签: spring servlets concurrency


    【解决方案1】:

    我认为您授予 Spring 会话互斥锁的功能超出了应有的范围。它只是一个存储在公共名称WebUtils.SESSION_MUTEX_ATTRIBUTE 下的会话属性,旨在用于synchronized 语句的表达式中。我不确定它如何用于“在集群环境中锁定会话对象”。下面是 Spring 自己代码中的 sn-p 用法:

    HttpSession session = request.getSession(false);
    if (session != null) {
        Object mutex = WebUtils.getSessionMutex(session);
        synchronized (mutex) {
            return handleRequestInternal(request, response);
        }
    }
    

    在一个 JVM 中对 mutex 对象的引用对另一个 JVM 将不可用,因此获取它的锁定不会对在另一个 JVM 中运行的代码产生任何影响。但是,servlet 规范确实包含以下内容:

    在标记为可分发的应用程序中,所有可分发的请求 会话的一部分必须一次由一个 JVM 处理。

    此要求至少从 2.3 开始就存在,并且可能导致分布式应用程序表现得好像 Spring 互斥体正在做某事,而事实上,它是容器强制请求由一个 JVM 处理。

    顺便说一句,这让我想起了几年前我在并发兴趣上发表的一篇文章,其中提到了 Spring 的会话互斥锁:

    JTaP article on stateful web apps

    根据评论更新:

    假设 JVM-1 和 JVM-2 构成集群中的两个节点。还假设 request-1 和 request-2 参与同一个会话。如果在 JVM-1 中处理 request-1,则在 request-1 完成之前无法在 JVM-2 中处理 request-2。但是,请求 2 可以由 JVM-1 并发处理。

    对于在不同 JVM 中处理请求的情况,这意味着由第一个请求 (JVM-1) 引起的任何会话更改将对第二个请求 (JVM-2) 可见。

    【讨论】:

    • “作为会话一部分的所有请求必须一次由一个 JVM 处理”是什么意思?规范是否规定了粘性会话,因为容器必须使用该技术来保证相同的会话始终由相同的 JVM 提供服务?或者这是否意味着容器必须保证(以某种方式)相同的会话将被原子地访问,而不管 JVM 是否正在为请求提供服务?
    猜你喜欢
    • 2018-10-11
    • 2015-07-27
    • 2010-09-19
    • 2011-06-18
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多