在我的项目中,我使用ehcache存储loggged用户详细信息和一些其他信息(哪个应用程序将在运行时使用它而不是从db获取)。以下是我的ehcache配置:
<cache
name="normalCache"
maxElementsInMemory="50000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="0"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>
但问题是大多数时间会话超时发生(即使用户不是非活动状态更多&gt; 30)。有时它发生了10分钟,...
所有操作都会尝试根据ehcache的每个请求检索用户对象。
我不确定ehcache将如何确定到期时间。
答案 0 :(得分:5)
当满足以下条件之一时,Ehcache会从缓存中驱逐对象:
尚未从ehcache(读取或更新)访问对象的时间超过timeToIdle
秒。如果未设置timeToIdle
,则此规则不适用。换句话说,即使在未设置timeToIdle
的情况下从未从缓存访问(读取或更新)对象,对象也有资格在缓存中保留无限时间。
对象在缓存中的时间超过timeToLive
秒。如果未设置timeToLive
,则此规则不适用。换句话说,一个对象有资格在缓存中保留无限时间。
缓存中的项目数已达到maxElementsInMemory
限制。在这种情况下,memoryStoreEvictionPolicy
开始执行并删除与驱逐策略匹配的元素,直到缓存中的元素数量变得小于maxElementsInMemory
限制,即使这些项目有资格在缓存中按照条件1号和2号。
希望澄清它!
答案 1 :(得分:1)
ehcache不保证将所有元素保留30分钟。
在你的配置中,你有一个50000的maxElementsInMemory。也许你已经达到了50000,因此你将overflowToDisk设置为false,因此最近最少使用的条目将被驱逐。
答案 2 :(得分:0)
<强>序言强>
我计划首先使用ehCache作为会话管理实现进行检查,如果你不能使用已经提供的,可能更适合的会话实现。如果您使用的是网络容器或完整的肉食服务器,那么您真的应该先尝试一下
<强>为什么强>
好。你很确定不能以正确的方式做到这一点。以下是一些提示,为什么您可能希望将ehCache用于会话
对于1,请检查是否可以选择像jetty这样的Web容器。你肯定会使用整个会话的网页访问,不会为你弹出。
对于2,请检查,如果Apache Shiro不符合您的要求。如果没有,ehCache可能是你的朋友。
3 ...欢迎来到俱乐部。
对于4 ...好吧,如果你没有看过这本手册,你也不会读这篇文章。
如何
如果您想使用ehCache实现会话管理,请确保您的数据是可序列化的。这将减少问题,让您使用ehCache的敏感功能。即持久化到磁盘,缓存节点,从中恢复,等等。
不为每个会话使用缓存,但一个缓存用于所有会话。 sessionId
是缓存中的关键字,值为Map
。不要忘记并发性(想想ajax调用)。最好使用ConcurrentHashMap
中的java.util.concurrent
。但也许你是Dr Heinz M. Kabutz并找到一种更酷的方法来做到这一点。
我发现使用大小比保存数量的元素更有帮助。您可能不知道,以后会存储哪些数据/对象。不要忘记设置持久性策略。我在这里使用存储到临时文件夹。
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir"/>
<cache name="vocCache"
eternal="false"
maxElementsInMemory="100MB"
maxElementsOnDisk="1GB"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
memoryStoreEvictionPolicy="LRU"
diskExpiryThreadIntervalSeconds="60">
<persistence strategy="localTempSwap" />
</cache>
因为我们想要实现会话管理器,所以我们不关心timeToLiveSeconds
。会话在一定的空闲时间后超时。因此,我们不会将元素约束为最大ttl,而是使用timeToIdleSeconds
让元素超时。
请勿使用timeToIdleSeconds
和timeToLiveSeconds
,因为您可以为要稍后添加的元素设置特定值。
<强>逐出强>
关于到期时间的一个注释。由于配置的时间,内存中的元素永远不会被驱逐。内存将累积,直到命中定义的内存约束。因此,如果您定义了100个元素,如果添加了101元素,则memoryStoreEvictionPolicy
将被触发,并且在此配置中,一个元素将被刷新到磁盘(ehCache 2.2)。对于磁盘存储,将有一个线程检查到期时间(diskExpiryThreadIntervalSeconds
)。请参阅documentation。
因此,您必须使用isExpired()
从缓存中检查检索到的元素,以确保它未过期。
所以最后,你最终会得到这样的东西:
获取强>
Cache cache = CacheManager.getInstance().getCache(CACHE_NAME);
Element elem = cache.get(identifier);
if (elem == null)
{
throw new SessionNotFoundException(identifier);
}
if (elem.isExpired())
{
throw new SessionExpiredException(identifier);
}
return elem.getObjectValue();
<强> PUT 强>
Cache cache = CacheManager.getInstance().getCache(CACHE_NAME);
// We use ttl = 0 and tti=<ttlInMinutes>, because session timeout is based on session idle timout.
element = new Element(identifier, new SessionElement(), Boolean.FALSE, (int) (timeToLive / VALUE_MS), 0);
cache.put(element);