【问题标题】:Hazelcast - Remove expired session from mapHazelcast - 从地图中删除过期会话
【发布时间】:2017-04-04 21:05:36
【问题描述】:

我的问题是关于 Hazelcast 如何从底层地图中删除过期会话。

我在 Tomcat 上运行一个大型 Java Web 应用程序,它使用基于 cookie 的会话。请求通过 Hazelcast 的 WebFilter。 WebFilter 配置为连接到外部 Hazelcast 集群并将会话存储在地图中。这是 web.xml 过滤器配置的子集。

<init-param> <param-name>use-client</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>map-name</param-name> <param-value>SessionMap</param-value> </init-param>

在 web.xml 中,我的 session-timeout 设置为 120(即 2 小时)。 Hazelcast 地图名为 SessionMap,其 TTL 为 24 小时。这里的想法是,我们希望结束 2 小时不活动的会话,但如果有人持续使用该应用程序,我们希望让会话最多持续 24 小时。

问题是,如果我让会话空闲,Tomcat 将在 2 小时后终止会话,但会话仍将保留在 Hazelcast 映射 (SessionMap) 中,直到 TTL。有没有办法让 Hazelcast 在 Tomcat 中过期时自动从底层地图中删除会话?

应用程序可以有大量会话,并且很少有会话会在整个 24 小时内保持活动状态,因此我们不希望在 Hazelcast 的内存中留下已经过期的会话。

我正在使用 Hazelcast 3.8。

编辑在 Hazelcast 文档 (http://docs.hazelcast.org/docs/3.5/manual/html/websessionreplication.html) 中,它说:

如果 Web 容器上的会话过期,Hazelcast 会自动从集群中删除会话。此删除由 com.hazelcast.web.SessionListener 完成,它是 javax.servlet.http.HttpSessionListener 的实现。

这是否仅适用于嵌入用于存储会话的 Hazelcast 集群?如果是这样,当会话存储在外部集群中时,是否有实现类似行为的解决方案?

【问题讨论】:

    标签: java tomcat hazelcast


    【解决方案1】:

    您提到的任何设置看起来都是正确的。 SessionListener 应该负责在 2 小时后删除过期的会话,并且地图的 ttl 应该负责在 12 小时后使条目过期。您可以从 web.xml 的 init-param 中删除 session-ttl-seconds,因为它对客户端/服务器模式没有影响。

    要确认过期会话是否正在从地图中删除,您可以实现一个轻量级的 MapEventListener。

    IMap map = hzInstance.getMap("sesssion-map");
    map.addEntryListener(new SessionMapEntryListener(), false);
    

    实现 MapEntry 监听器。您也可以根据需要实现其他接口。例如,EntryAddedListener, EntryRemovedListener, EntryUpdatedListener, EntryEvictedListener

    private static class SessionMapEntryListener implements MapListener, EntryExpiredListener {
    
        @Override
        public void entryExpired(EntryEvent entryEvent) {
            System.out.println("EntryExpiredEvent triggered. Expired Entry = " + entryEvent.getKey());
        }
    }
    

    【讨论】:

    • 我会尽快尝试添加一个地图监听器,但我有 98% 的把握确定它不会从地图中删除。我开始深入研究 hazelcast-wm 代码。当会话被销毁时,它们的 SessionListener 调用 WebFilter.destroyOriginalSession。这最终会调用 WebFilter.destroySession,但会为 invalidate 参数传入 false。这最终会进入 DeleteSessionEntryProcessor ,并且看起来 process 方法只会在 invalidate 为真时删除映射条目。绝对有可能我遗漏了一些东西,但我不知道这将如何删除地图条目。
    • 我在这里打开了一个关于此的错误:github.com/hazelcast/hazelcast-wm/issues/48
    猜你喜欢
    • 1970-01-01
    • 2022-10-12
    • 2012-02-02
    • 2017-03-16
    • 2022-11-10
    • 2011-11-22
    • 2019-12-31
    • 2014-03-26
    • 2023-04-06
    相关资源
    最近更新 更多