繁体   English   中英

使用Ehcache的WebApp会话管理

[英]WebApp Session Management using Ehcache

在我的项目中,我使用ehcache存储登录的用户详细信息和一些其他信息(哪个应用程序将在运行时使用它而不是从db获取)。 以下是我的ehcache配置:

<cache 
    name="normalCache"
    maxElementsInMemory="50000" 
    eternal="false"
    timeToIdleSeconds="1800" 
    timeToLiveSeconds="0"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LRU"
/>

但问题是会话超时发生的大部分时间(即使用户不是非活动状态> 30)。 有时会发生10分钟,......

所有操作都将尝试从ehcache的每个请求中检索用户对象。

我不确定ehcache将如何确定到期时间。

当满足以下条件之一时,Ehcache会从缓存中驱逐对象:

  1. 尚未从ehcache(读取或更新)访问对象超过timeToIdle秒。 如果未设置timeToIdle则此规则不适用。 换句话说,即使没有设置timeToIdle ,对象也有资格在缓存中保留无限时间,即使它从未从缓存中访问(读取或更新)。

  2. 对象已在缓存中超过timeToLive秒。 如果未设置timeToLive则此规则不适用。 换句话说,对象有资格在缓存中保留无限时间。

  3. 缓存中的项目数已达到maxElementsInMemory限制。 在这种情况下, memoryStoreEvictionPolicy开始运行并删除与驱逐策略匹配的元素,直到缓存中的元素数量变得小于maxElementsInMemory限制,即使这些项目符合条件1和2的条件在缓存中。

希望澄清一下!

ehcache不保证将所有元素保留30分钟。

在您的配置中,您有一个50000的maxElementsInMemory。也许您已经达到了50000,因此您将overflowToDisk设置为false,因此最近最少使用的条目将被逐出。

前言

我正在计划使用ehCache作为会话管理实现首先检查,如果你不能使用已经提供的,可能更适合的会话实现。 如果您正在使用Web容器或完整的jeee服务器,您真的应该先尝试这个


为什么

好的。 你很确定不能以正确的方式做到这一点。 以下是一些提示,为什么您可能希望将ehCache用于会话

  1. 您的服务不是jee服务器/ Web容器的一部分。
  2. 您的服务是无状态的,但有时您需要状态(框架代码)。
  3. 由于您和可区分客户端之间的代理,您无法区分呼叫,例如,您是某种服务/服务的中间件,它不提供默认的可区分数据,但有条件地使用userId或sessionId等参数但不是组成性的。
  4. 你只是没有RTFM而且想按照自己的方式去做。

对于1,请检查是否可以选择像jetty这样的Web容器。 你肯定使用整个会话的web访问thingy不会弹出给你。

请检查2,如果Apache Shiro不能做你想要的。 如果没有,ehCache可能是你的朋友。

3 ...欢迎来到俱乐部。

对于4 ...好吧,我想如果你没有看过这本手册,你也不会读到这本书。


如何

如果您想使用ehCache实现会话管理,请确保您的数据是可序列化的。 这将减少问题,让您使用ehCache的敏感功能。 即持久化到磁盘,缓存节点,从中恢复,等等。

不要使用为每个会话的所有会话缓存,但一个缓存。 sessionId是缓存中的键,值将转到Map 不要忘记并发性(想想ajax调用)。 最好使用java.util.concurrentConcurrentHashMap 但也许你是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让元素超时。 请勿使用timeToIdleSecondstimeToLiveSeconds因为您可以为稍后要添加的元素设置特定值。

赶出

关于到期时间的一个注释。 由于配置的时间,内存中的元素永远不会被驱逐。 内存将累积,直到命中定义的内存约束。 因此,如果您定义了100个元素,如果添加了101元素,则将触发memoryStoreEvictionPolicy并且在此配置中将一个元素刷新到磁盘(ehCache 2.2)。 对于磁盘存储,将有一个线程检查到期时间( diskExpiryThreadIntervalSeconds )。 请参阅文档 因此,您必须使用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();

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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM