淘气backOffIfDiskSpoolFull

时间:2018-07-14 22:25:37

标签: hibernate spring-boot spring-data-jpa ehcache

当我的Spring Boot + Data JPA 1.5应用程序承受重负载时,过了一会儿(在本例中为几分钟),该存储库将暂停20-30秒,因为EhCache "backs-off" by putting the thread to sleep因为其磁盘后台处理程序已满:

"pool-2-thread-1" sleeping[0x00007fc1a95ae000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep
    at ehcache.Cache.backOffIfDiskSpoolFull
    at ehcache.Cache.putInternal
    at ehcache.Cache.put
    at ehcache.Cache.put
    ... many Hibernate, Spring, Sun frames
    at com.sun.proxy.$Proxy155.save

(为清楚起见,从ehcache修剪net.sf.

结果,性能骤降,这让我很难过。

定义了ehcache.xml;我只添加了hibernate-ehcache依赖项,并通过@EnableCaching批注启用了缓存。尽管未提供ehcache.xml,但Hibernate仍明显使用Ehcache,如上面的stacktrace所示。

我想将EhCache重新配置为不使用DiskStore,而是做所有其他的魔术(通过Spring Boot,Spring Data,Hibernate等)。为了避免尝试重新创建现在看来已经存在的有效/神奇的ehcache.xml,是否存在一个EhCache bean,我可以在其中禁用持久性或等效的外科手术?另外,是否可以打印出有效的Ehcache配置?

2 个答案:

答案 0 :(得分:1)

磁盘存储在Ehcache配置中定义。在ehcache.xml中。

因此,从ehcache.xml删除磁盘存储是一种解决方法。

根据您添加的解释:Hibernate尝试与您友好,并使用默认参数创建缓存。但是使用这些参数是一个非常糟糕的主意。

您需要对缓存配置进行一些思考。

  • 它应该包含几个元素?
  • 它们应该过期吗?
  • 我需要磁盘吗? (大多数情况下,答案的确是“否”)

如果不这样做,最终将得到陈旧的数据或OutOfMemoryError s。

因此,我强烈建议您使用经过深思熟虑的ehcache.xml而不是休眠魔术。

答案 1 :(得分:0)

带有Spring Data JPA的Spring Boot 1.5使用Hibernate 5.0.12.Final;并且,Hibernate 5.0.12.Final在内部使用Ehcache 2.4.3。要禁用磁盘写入,您将需要在Hibernate使用的默认缓存配置中禁用磁盘,并在任何应用程序定义的缓存中禁用磁盘使用,例如:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
  <defaultCache
      maxElementsInMemory="10000"
      eternal="false"
      timeToIdleSeconds="120"
      timeToLiveSeconds="120"
      overflowToDisk="false"
      maxElementsOnDisk="0"
      diskPersistent="false"
      diskExpiryThreadIntervalSeconds="120"
      memoryStoreEvictionPolicy="LRU"
      />

  <cache name="my-cache-1" />
  ...
  <cache name="my-cache-n" />
</ehcache>