【发布时间】:2017-05-28 23:04:29
【问题描述】:
我们有一个使用 spring mvc 和 spring security 等的网络应用程序。当会话超时时,我们要清除数据 X。
我们注册一个如下所示的监听器:
public class SessionDestroyedEventListener implements ApplicationListener<HttpSessionDestroyedEvent> {
@Override
public void onApplicationEvent(HttpSessionDestroyedEvent event) {
for (SecurityContext securityContext : event.getSecurityContexts()) {
AuthenticationDetails authenticationDetails = getAuthenticationDetails(securityContext.getAuthentication());
// clean out data X
}
}
}
定义为一个bean
@Bean
public SessionDestroydEventListener sessionDestroydEventListener() {
return new SessionDestroydEventListener();
}
正如我所说,此侦听器的主要用途是在会话长时间处于非活动状态时删除数据 X。但是,由于我们无法弄清楚的原因,有时会在超时之前调用此侦听器,从而导致数据 X 被删除并且用户会话中断。这些事件意外发生,导致糟糕的用户体验(用户在积极使用我们的网站时被注销)。
我试图找出为什么在我不希望调用 SessionDestroyedEventListener.onApplicationEvent 时调用它。我正在努力寻找有关此问题或其他有类似问题的有用信息。
我们遇到的一个问题是,当这种情况发生时,我们的日志是静默的 - 没有堆栈跟踪,当突然调用 SessionDestroyedEventListener 时,通常看起来一切正常。
整个设置很复杂,我觉得在这个 stackoverflow 报告中实际解决我们的核心问题可能很困难,我主要对如何排除故障的提示感兴趣 - 有没有什么地方可以找到有关导致事件的原因的信息(是超时、来自浏览器的错误 jsessionid 等)还是某种设置方式,以便我们获得有关正在发生的事情的更多信息。
尽管我可以提到,我们有一个 apache 前端,可以将负载平衡到两个或多个 Wildfly 服务器,每个服务器都运行我们的 Web 应用程序。使用粘性会话,浏览器会话使用 jsessionid 锁定到 Wildfly 服务器。
编辑:澄清一下,主要问题不是我们真的要检查为什么会话被破坏,问题是会话在超时之前完全被破坏。知道原因会很好,因为它可以让我们了解会话是如何被破坏的,这样我们就可以找到问题的根源。
【问题讨论】:
-
会不会是即使用户在站点上仍然处于活动状态,但与服务器没有通信并且会触发超时?我已经看到了这种情况,我们通过实现心跳信号来保持会话处于活动状态,从而解决了这个问题。
-
@kaqqao:我们的网站使用频繁的从网站重新加载页面,并且在用户可能在页面上逗留而不向服务器发送查询的地方,我们有一个像你一样的心跳信号。在查询从浏览器发送到 Wildfly 服务器后不久(2-30 秒)发生随机注销的情况并不少见(我们可以在日志时间戳中看到它)。