【问题标题】:WebApp Session Management using Ehcache使用 Ehcache 的 WebApp 会话管理
【发布时间】:2014-08-15 13:09:58
【问题描述】:

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

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

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

所有操作都会尝试从 ehcache 中获取每个请求的用户对象。

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

【问题讨论】:

  • 嗨 Ramki,我也在尝试实现 ehcache,如果是这样,您能否提供任何好的指南或教程,请提供链接。
  • 您好,您使用的是什么应用服务器?

标签: java session web-applications ehcache session-management


【解决方案1】:

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

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

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

  3. 缓存中的项目数已达到maxElementsInMemory 限制。在这种情况下,memoryStoreEvictionPolicy 开始起作用并删除与驱逐策略匹配的元素,直到缓存中的元素数量小于maxElementsInMemory 限制,即使这些项目根据条件 1 有资格在缓存中和第 2 号。

希望能澄清一下!

【讨论】:

    【解决方案2】:

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

    在您的配置中,您的 maxElementsInMemory 为 50000。也许您曾一度达到 50000,因此当您将 overflowToDisk 设置为 false 时,最近最少使用的条目将被驱逐。

    【讨论】:

      【解决方案3】:

      序言

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


      为什么

      好的。你肯定不会用正确的简单方法来做这件事。这里有一些提示,为什么您可能希望将 ehCache 用于会话

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

      对于 1,请检查是否可以选择像码头这样的网络容器。你当然会使用整个会话的网络访问,这不会为你弹出。

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

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

      对于4...好吧,我想如果您没有阅读手册,您也不会阅读此内容。


      如何

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

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

      驱逐

      关于到期时间的注释。内存中的元素永远不会因为配置的时间而被驱逐。内存将累积,直到达到定义的内存约束。因此,如果您定义 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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-03
        • 1970-01-01
        • 2011-07-03
        • 2018-06-21
        • 1970-01-01
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多