我的问题是关于Hazelcast如何从底层地图中删除过期的会话。
我在Tomcat上运行一个使用基于cookie的会话的大型Java Web应用程序。请求通过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小时)。名为SessionMap的Hazelcast地图的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群集?如果是这样,当会话存储在外部集群中时,是否存在实现类似行为的解决方案?
答案 0 :(得分:3)
无论您提到的设置是什么,都是正确的。 SessionListener
应该在2小时后处理已过期的会话,并且地图的ttl应该在12小时后处理该条目。您可以从session-ttl-seconds
web.xml中删除init-param
,因为它对客户端/服务器模式没有影响。
要确认是否从地图中删除了过期的会话,您可以实现轻量级的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());
}
}