【问题标题】:Ehcache - java.io.EOFException for disk persistent cache for removeAll operationEhcache - 用于 removeAll 操作的磁盘持久缓存的 java.io.EOFException
【发布时间】:2019-03-11 07:47:24
【问题描述】:

我们在 Spring Boot 应用程序中使用 ehcache。我们的spring boot版本是2.0.3.RELEASE,spring-boot-starter-cache 2.0.3.RELEASE使用ehcache 3.5.2。

我们使用 ehcache 的动机是它既符合 jsr107 标准,又提供堆外支持。

下面是我们的 spring 配置:

@Configuration
@ConditionalOnWebApplication
@EnableCaching
public class CacheConfig {
    @Autowired
    private ApplicationContext context;

    @Bean
    public JCacheManagerFactoryBean jCacheManagerFactoryBean() throws IOException {
        JCacheManagerFactoryBean jCacheManagerFactoryBean = new JCacheManagerFactoryBean();
        Resource resource = context.getResource("classpath:mts/ehcache.xml");
        jCacheManagerFactoryBean.setCacheManagerUri(resource.getURI());
        return jCacheManagerFactoryBean;
    }

    @Bean
    public JCacheCacheManager ehCacheCacheManager() throws IOException {
        Properties props = System.getProperties();
        props.setProperty(Caching.JAVAX_CACHE_CACHING_PROVIDER, "org.ehcache.jsr107.EhcacheCachingProvider");
        JCacheCacheManager jCacheCacheManager = new JCacheCacheManager();
        jCacheCacheManager.setCacheManager(jCacheManagerFactoryBean().getObject());
        jCacheCacheManager.setTransactionAware(true);
        return jCacheCacheManager;

    }

}

我们在生产中面临的问题是,对于一个中等大小的磁盘持久缓存,我们在 removeAll 操作中出现以下 java.io.EOFException 错误:

Error : RuntimeException: java.io.EOFException 
java.lang.RuntimeException: java.io.EOFException
        at org.terracotta.offheapstore.disk.storage.FileBackedStorageEngine$FileChunk.readKeyBuffer(FileBackedStorageEngine.java:541) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.disk.storage.FileBackedStorageEngine.readKeyBuffer(FileBackedStorageEngine.java:265) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.storage.PortabilityBasedStorageEngine.readKey(PortabilityBasedStorageEngine.java:119) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.OffHeapHashMap$DirectEntry.<init>(OffHeapHashMap.java:1540) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.OffHeapHashMap$EntryIterator.create(OffHeapHashMap.java:1518) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.OffHeapHashMap$EntryIterator.create(OffHeapHashMap.java:1511) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.OffHeapHashMap$HashIterator.next(OffHeapHashMap.java:1407) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.AbstractLockedOffHeapHashMap$LockedEntryIterator.next(AbstractLockedOffHeapHashMap.java:399) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.AbstractLockedOffHeapHashMap$LockedEntryIterator.next(AbstractLockedOffHeapHashMap.java:392) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.terracotta.offheapstore.concurrent.AbstractConcurrentOffHeapMap$AggregateIterator.next(AbstractConcurrentOffHeapMap.java:553) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore$1.next(AbstractOffHeapStore.java:499) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore$1.next(AbstractOffHeapStore.java:489) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.ehcache.core.EhcacheBase$Jsr107CacheBase.removeAll(EhcacheBase.java:708) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at org.ehcache.jsr107.Eh107Cache.removeAll(Eh107Cache.java:304) ~[ehcache-3.5.2.jar!/:3.5.2 7941fa2573343b31ae56a12564404552c6d6eff0]
        at com.mycompany.myproject.services.cache.service.impl.CacheService.doClearCacheWithName(CacheService.java:56) ~[MyProjectServicesCache_classes.jar!/:?]  

调用 removeAll 操作的代码没有什么特别之处。只需获取带有名称的缓存并调用 clear all:

private void doClearCacheWithName(String cacheName) {
    Cache<Object, Object> cache = cacheManager.getCache(cacheName);
    if (cache == null) {
        throw new MyProjectException(String.format("Cache with name : %s does not exist!", cacheName));
    }
    logger.info(String.format("Clearing cache with name : %s", cacheName));
    cache.removeAll();
}

这是 ourBigCache 的生产配置:

<cache alias="ourBigCache">
        <expiry>
            <ttl unit="seconds">21600</ttl> 
        </expiry>
        <resources>
            <heap unit="entries">1000</heap>
            <disk unit="MB">4096</disk>
        </resources>
    </cache>

我们无法在本地或测试环境中重现此内容。

请注意,这个缓存的使用率非常高(生产中的读取计数非常高),但我想这应该没有任何区别。

我找不到任何类似的报告问题。提到了一些非常老的磁盘问题,但它们太老了,不相似:

https://sourceforge.net/p/ehcache/discussion/322278/thread/e7a62df3/ http://forums.terracotta.org/forums/posts/list/2694.page

任何帮助将不胜感激。

问候

【问题讨论】:

    标签: spring ehcache spring-cache ehcache-3


    【解决方案1】:

    复制自我对 ehcache-users 的回复:

    这很可能只是 https://github.com/ehcache/ehcache3/issues/2542 的另一个症状,已在 74239a93e14eb7477841fffa36c971ef9e930686 中修复

    不幸的是,此修复尚未在任何地方合并。如果你想选择这个,你可以削减你自己的 master 构建(这可能是一件好事来验证)。否则,您将不得不等待 3.7 线上的第一个 dot-release(此时时间线未知)。

    克里斯

    【讨论】:

    • thanx 将尝试应用您的修复程序。问候
    • 对于所有感兴趣的人来说,Chris 提到的修复方法似乎可以解决问题。已经生产一周了,没有任何错误:)
    猜你喜欢
    • 2016-02-26
    • 2016-09-02
    • 2014-05-05
    • 2018-04-14
    • 2018-01-21
    • 1970-01-01
    • 2016-04-24
    • 2020-07-21
    • 2010-12-16
    相关资源
    最近更新 更多