为什么ehcache死锁?

时间:2014-08-02 12:04:18

标签: spring tomcat cluster-computing deadlock ehcache

我们的一个项目使用spring 3.2和tomcat 7.0的集群,并使用ehcache2.8.0以获得更好的性能,我们也使用RMI进行复制,如http://ehcache.org/documentation/replication/rmi-replicated-caching。配置如:

<bean id="method-cache-key-generator" class="com.services.cache.MethodCacheKeyGenerator" />
<bean id="service-cache-manager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehcache-manager" />
</bean>
<bean id="ehcache-manager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />

和:

<cache:advice id="user-service-read-cache-advice"
      cache-manager="service-cache-manager" key-generator="method-cache-key-generator">
  <cache:caching cache="userCache">
      <cache:cacheable method="get*" />
      <cache:cacheable method="find*" />
  </cache:caching>
</cache:advice>
<cache:advice id="user-service-write-cache-advice"
      cache-manager="service-cache-manager" key-generator="method-cache-key-generator">
  <cache:caching cache="userCache">
    <cache:cache-evict method="create*" all-entries="true" />
    <cache:cache-evict method="update*" all-entries="true" />
    <cache:cache-evict method="remove*" all-entries="true" />
    <cache:cache-evict method="reset*" all-entries="true" />
    <cache:cache-evict method="change*" all-entries="true" />
  </cache:caching>
</cache:advice>

<bean id="cached-user-info-service" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target" ref="original-user-info-service" />
  <property name="interceptorNames">
    <list>
      <value>user-service-clone-advice</value>
      <value>user-service-read-cache-advice</value>
    </list>
  </property>
</bean>
<bean id="cached-user-service" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target" ref="original-user-service" />
    <property name="interceptorNames">
    <list>
      <value>user-service-write-cache-advice</value>
    </list>
      </property>
</bean>

我们发现最终用户在短时间内使用系统后无法登录,必须重新启动tomcat才能解决问题。但是,我们的测试人员无法在同一系统服务器上重现此问题。

我们使用jconsole检查服务器并发现大量线程正在等待线程锁定,并且这个线程在ehcache上死锁。

堆栈的一部分是:

java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
net.sf.ehcache.util.concurrent.ConcurrentHashMap$Node.tryAwaitLock(ConcurrentHashMap.java:687)
net.sf.ehcache.util.concurrent.ConcurrentHashMap.internalClear(ConcurrentHashMap.java:2016)
net.sf.ehcache.util.concurrent.ConcurrentHashMap.clear(ConcurrentHashMap.java:2680)
net.sf.ehcache.store.cachingtier.OnHeapCachingTier.clear(OnHeapCachingTier.java:213)
net.sf.ehcache.store.CacheStore.removeAll(CacheStore.java:250)
net.sf.ehcache.Cache.removeAll(Cache.java:2451)
net.sf.ehcache.Cache.removeAll(Cache.java:2436)
org.springframework.cache.ehcache.EhCacheCache.clear(EhCacheCache.java:74)
org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheEvicts(CacheAspectSupport.java:243)
org.springframework.cache.interceptor.CacheAspectSupport.inspectAfterCacheEvicts(CacheAspectSupport.java:227)
org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:212)
org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66)

出于某些原因,我们无法要求最终用户帮助我们重现此错误。我的问题是在什么样的条件下ehcache不会释放写锁?  任何建议我们找到解决这个问题的方法将不胜感激。

0 个答案:

没有答案