[英]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”事件。
题:
附加日志,您可以看到第一行和第二行是主会话,第三行是备份会话,这可以通过行尾的会话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()方法的第二次调用延迟会发生超时。
注销时的简单解决方案将用户重定向到应用程序外部的网页。
您可能有兴趣看一下:
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!**173379423**!1400921280!1508478820022
第三条日志行指示在不同的主jvm /节点中创建的会话( 173379423 )比较前两个( -795465203 )。
这可能与session.invalidate调用无关,但是它存在创建两个会话(两个不同的主节点)的问题,并且在超时后过期
我可以想到两种可能的用例
更新:
- 为什么备份会话不触发会话创建事件? 2.理想情况下,备份会话是否应该与主会话透明地超时?
There is no second session being created!!.
让我尝试解释流程。
节点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.