繁体   English   中英

如何让主要会话与Weblogic上的次要会话共享“会话超时”?

[英]How to let Primary Session share “session time out” with Secondary Session on Weblogic?

更新问题描述以更具体和详细。

我有一个weblogic 12c ,配置了一个集群,集群中有4个节点实例,默认负载算法为Round Robin ,复制类型为MAN 我在所有4个节点上部署了一个Web应用程序。

我第一次设计的是:

用户会话无效后,执行与注销相关的业务逻辑。 将逻辑代码放入实现HttpSession接口的SessionListener.java的“ sessionDestroyed”方法中。 如您所知,会话无效可能是由2种情况引起的,一种是手动注销,另一种是J2ee容器触发超时。 由于第二种情况,发生了我的问题。

问题:

“ SessionDestroyed”事件中的业务逻辑代码在一个用户超时中执行了两次,这是不期望的,并导致业务错误。 我发现节点A上的主Http会话和节点B上的备份会话都触发了weblogic“ SessionDestroyed”事件。

题:

  1. 尽管节点A上的主会话已经超时,为什么节点B上的备份会话触发了会话超时事件?
  2. 如何让备份会话知道主会话已经失效?

附加日志,您可以看到第一行和第二行是主会话,第三行是备份会话,这可以通过行尾的会话ID来证明。

DEBUG Oct-20-17 01:53:40 [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-27  ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022 Created at Fri Oct 20 01:53:40 EDT 2017
DEBUG Oct-20-17 02:54:05 [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-46  ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022 Destroyed at Fri Oct 20 02:54:05 EDT 2017
DEBUG Oct-20-17 02:55:12 [[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-46  ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!173379423!1400921280!1508478820022 Destroyed at Fri Oct 20 02:55:12 EDT 2017

以下是我的weblogic配置:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
  <session-descriptor>
    <cookie-path>/AppName</cookie-path>
    <persistent-store-type>replicated</persistent-store-type>
    <http-proxy-caching-of-cookies>true</http-proxy-caching-of-cookies>
    <cookie-secure>true</cookie-secure>   
  </session-descriptor>  
</weblogic-web-app>

这是我在Web应用程序内部的web.xml中配置的会话:

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

这是我的SessionListener.java:

public class SessionListener implements HttpSessionListener {

    private static Logger logger = Logger.getLogger(SessionListener.class);

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        if (logger.isDebugEnabled()) {
            logger.debug("Session: " + se.getSession().getId() + " Created at " + (new java.util.Date()));
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        /**
         * The business logic code related to logout action
         * would be executed twice here, this is not what I want.
         **/
        if (logger.isDebugEnabled()) {
            logger.debug("Session: " + se.getSession().getId() + " Destroyed at " + (new java.util.Date()));
        }
    }
}

此代码用于手动注销:

@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest request,
            HttpServletResponse response) throws Exception {

        ...
        // Business Logic for Logout
        ...

        request.getSession().invalidate();

        CommonViewObject vo = new CommonViewObject();
        return renderReponse(request, response, vo, "Login");
}

任何建议,将不胜感激。 我需要解决这个问题,谢谢!

如果您强制用户通过invalidate()方法注销,则HttpSessionListener sessionDestroyed()方法将被调用两次,一次是在用户注销时,另一次是在某个延迟时间段之后。

如果注销后将用户重定向回应用程序中的网页,则会发生这种情况 实际上,您正在做的是启动另一个会话 (如果您尚未向所有网页添加安全性/身份验证要求,这可能不会立即显现),并且sessionDestroyed()方法的第二次调用延迟会发生超时。

注销时的简单解决方案将用户重定向到应用程序外部的网页。

您可能有兴趣看一下:

JDev / ADF:如何将用户登录/注销/超时记录到数据库

JSP Servlet会话invalidate()不会使会话为空

Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!**173379423**!1400921280!1508478820022

第三条日志行指示在不同的主jvm /节点中创建的会话( 173379423 )比较前两个( -795465203 )。

这可能与session.invalidate调用无关,但是它存在创建两个会话(两个不同的主节点)的问题,并且在超时后过期

我可以想到两种可能的用例

  1. LB有粘性问题。 它可能将请求转发到另一个节点,该节点在60分钟后过期
  2. 在窗口群集将主会话复制到新节点(节点c)的过程中,主jvm(节点a)可能变坏并恢复了自己的状态,但是由于运行状况监控器间隔,LB可能未注意到(节点a),并且继续使用原始主节点jvm(节点a)

更新:

  1. 为什么备份会话不触发会话创建事件? 2.理想情况下,备份会话是否应该与主会话透明地超时?
  There is no second session being created!!.

让我尝试解释流程。

  • LB(F5)从客户端收到第一个请求。
  • LB将流量作为循环基础路由到节点。 选择的节点A
  • 节点A生成会话,并标记为“主”,然后根据其群集排名(假设节点B)创建会话,并将sessionid作为Cookies的一部分传递,以进行进一步的通信。

  • 向LB的进一步请求,LB将检查Cookies,并根据服务器标识符将流量路由到节点A。

  • 节点A发生故障/ Lb到节点A之间的连接问题,现在LB无法基于Cookie的信息进行路由,因此LB可以基于Round Robin选择任何节点并将请求发送到新的节点(节点D)。 此时,节点D根据Cookie信息作为部分请求传递并标记为主要,从而从次要中拉出会话,而节点B将保持次要。

    • 注意**,如果我们已经使用HttpClusterServlet代理(例如apache代理)并使用和(Weblogic插件( HttpClusterServlet ))在weblogic前面进行负载平衡,则HttpClusterServlet应该能够收集辅助服务器信息(主机和端口)并将流量路由到辅助后台服务器。 现在,节点B将成为主要节点,而新的辅助节点将根据节点B的群集排名进行选择。

所有会话复制对客户端都是透明的,在上述情况下不会创建第二个会话。

注意**,在两种情况下(基于LB /代理的路由),在节点A中创建的会话都被视为孤立会话,因为该会话具有新的主节点和辅助节点。 因此,当用户会话无效时,它将在当前的主节点和辅助节点中均无效。

Weblogic文档提供了此用例的其他信息。

建议根据访问日志/应用程序日志来跟踪会话,以验证呼叫何时移至下一个节点。 还要确保在同一时间段内访问日志中的LB健康监视器请求

还建议确保LB配置了Cookie持久性配置文件。

我猜您正在使用默认的spring安全配置,默认情况下会启用CSRF检查,因此您可能需要禁用它并再次检查

http.csrf().disable()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM