java – Http Sessions在Tomcat中的生命周期

我有一项任务是向站点管理员显示用户名列表以及每个用户当前使用的tomcat会话数(以及其他一些支持相关信息).

我将经过身份验证的用户保留为应用程序上下文属性,如下所示(不必要的细节).

Hashtable<String, UserInfo> logins //maps login to UserInfo

UserInfo定义为

class UserInfo implements Serializable {
String login;
private transient Map<HttpSession, String> sessions = 
      Collections.synchronizedMap(
             new WeakHashMap<HttpSession, String>() //maps session to sessionId
      );
...
}

每次成功登录都会将会话存储到此会话映射中.
sessionDestroyed()中的HttpSessionsListener实现从此映射中删除已销毁的会话,如果sessions.size()== 0,则从登录中删除UserInfo.

一些用户不时会出现0个会话.同行评审和单元测试表明代码是正确的.所有会话都是可序列化的.

是否有可能Tomcat将会话从内存卸载到硬盘驱动器,例如当有一段不活动时间(会话超时设置为40分钟)?从GC的角度来看,还有其他会话被“丢失”的情况,但是没有调用HttpSessionsListener.sessionDestroyed()吗?

J2SE 6,Tomcat 6或7独立,行为在任何操作系统上都是一致的.

您是否发现重启Tomcat后出现问题? Tomcat会在成功关闭期间将活动会话序列化为磁盘,然后在启动时反序列化 – 我不确定这是否会导致对HttpSessionListener.sessionCreated()的调用,因为会话未严格创建,只是反序列化(这可能不正确(!),但可以相当容易地测试).

您是否还将结果与Tomcat经理会话统计数据进行了比较?它会记录活动会话的数量,并且应该与您的数据相关联,如果没有,您就知道您的代码是错误的.

此外,可能与您的问题无关,但是您有充分的理由使用Hashtable和WeakHashMap吗?如果我需要一个线程安全的Map实现,我倾向于使用ConcurrentHashMap,它的性能要好得多.

相关文章
相关标签/搜索