【问题标题】:ehcache based on dateehcache 基于日期
【发布时间】:2012-12-06 05:45:59
【问题描述】:

我正在使用 ehcache 2.5.4。

我有一个对象需要全天缓存并在每天上午 00:00 用新值刷新。

目前使用 ehcache 配置,我只能设置生存时间和空闲时间,但这取决于我创建对象的时间或使用它的时间。即:

    <cache
    name="cache.expiry.application.date_status"
    maxElementsInMemory="10"
    eternal="false"
    timeToIdleSeconds="60"
    timeToLiveSeconds="50" />

有没有办法让 ehcache 根据特定时间使特定缓存过期。

【问题讨论】:

  • 不可能直接。使用外部 CRON 触发器 (quartz-scheduler?) 手动清除缓存怎么样?

标签: java hibernate caching ehcache


【解决方案1】:

我通过像这样扩展 Ehcache 的 Element 类来做到这一点:

class EvictOnGivenTimestampElement extends Element {

    private static final long serialVersionUID = ...;
    private final long evictOn;

    EvictOnGivenTimestampElement(final Serializable key, final Serializable value, final long evictOn) {
        super(key, value);
        this.evictOn = evictOn;
    }

    @Override
    public boolean isExpired() {
        return System.currentTimeMillis() > evictOn;
    }
}

剩下的就是将EvictOnGivenTimestampElement对象的新实例放入缓存而不是Element

这种方法的优点是您不必担心外部 cronjobs 等。 明显的缺点是对 Ehcache API 的附件,我希望它不会经常更改。

【讨论】:

  • 这似乎是一种非常巧妙的方法。我可以用注释来做吗?还是我需要手动创建CacheManager。我将它与 Spring 和 Hibernate 一起使用。
  • Element 是一个非常基本的 Ehcache 概念,与CacheManager 没有直接关系。关于注释 - 我不知道,因为我不使用注释......如果你想在不太可能支持的注释中设置过期,但你总是可以推出你自己的扩展,它可以按照你想要的方式工作。跨度>
  • 为什么我们不能在插入 Element 到缓存时使用 setTimeToLive()。再次创建 EvictOnGivenTimestampElement 类需要什么?
【解决方案2】:

EHCache 仅支持在一定时间后驱逐(在缓存中或由于不活动)。但是,您应该可以通过使用以下方式安排删除来相当轻松地完成此操作:

    Timer t = new Timer(true);
    Integer interval = 24 * 60 * 60 * 1000; //24 hours
    Calendar c = Calendar.getInstance();
    c.set(Calendar.HOUR, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);


    t.scheduleAtFixedRate( new TimerTask() {
            public void run() {
                Cache c = //retrieve cache                  
                c.removeAll();                                            
            }
        }, c.getTime(), interval);

这个基本示例使用 Java Timer 类进行说明,但可以使用任何调度程序。每 24 小时,从午夜开始 - 这将运行并从指定的缓存中删除所有元素。实际的run 方法也可以修改为删除符合特定条件的元素。

您只需要确保在应用程序启动时启动它。

【讨论】:

    【解决方案3】:

    在 Ehcache 3.2 中,我实现了 Expiry 扩展。

    public class EvictAtMidnightExpiry implements Expiry {
    
        @Override
        public Duration getExpiryForCreation(Object key, Object value) {
            DateTime now = new DateTime();
            DateTime resetAt = now.plusDays(1).withTimeAtStartOfDay();
            long difference = resetAt.toDateTime().getMillis() - now.getMillis();
            return Duration.of(difference, TimeUnit.MILLISECONDS);
        }
    
        @Override
        public Duration getExpiryForAccess(Object key, ValueSupplier value) {
            return null;
        }
    
        @Override
        public Duration getExpiryForUpdate(Object key, ValueSupplier oldValue, Object newValue) {
            return null;
        }
    }
    

    现在,我也有日志记录等,但我最小化了我的代码以保持整洁。

    然后你只需要在你的配置生成器中配置它。

    CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(1000)).withExpiry(new EvictAtMidnightExpiry()).build()
    

    显然,Ehcache 在 API 上有所改进,从 2.5 到 3.2,因为您不需要创建自己的“元素”并确保使用它来启动过期或驱逐策略。这些策略现在是缓存绑定的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 2014-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多