【问题标题】:EH-Cache with Spring Cache manager not working as expected带有 Spring Cache 管理器的 EH-Cache 未按预期工作
【发布时间】:2016-05-13 14:48:21
【问题描述】:

我们有基于 spring(3.2.9.Release) 的 java web 应用程序,并使用 hibernate 进行数据库操作。 我们目前有使用通过 WebSphere 服务器配置的 Dynacache 并使用 jndi 映射的缓存机制。我们在第一页加载时从数据库中检索所有内容并将其存储在 Dynacache 中。由于每次都是外部调用,所以我们想实现 Eh-Cache 并提高性能。但令人惊讶的是,Eh-Cache 的性能不如 Dynacache 并且加载页面需要很长时间。下面是我们对 Eh-Cache 的配置:

xml配置:

<bean id="cacheService" class="com.wlp.sales.ols.core.api.cache.CacheService"></bean>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehcache" />
    </bean>

<bean id="ehcache"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="/WEB-INF/configs/EhCache/ehcache.xml" />
        <property name="shared" value="true" />

ehcache.xml

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">

    <cache name="contentCache" 
        maxEntriesLocalHeap="10000"
        maxEntriesLocalDisk="1000" 
        eternal="true" 
        diskSpoolBufferSizeMB="20"
        timeToIdleSeconds="0" timeToLiveSeconds="0"
        memoryStoreEvictionPolicy="LRU" 
        transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>

</ehcache> 

依赖关系:

<!-- ehCache -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>

我们有一个缓存实现类,它将使用 get 和 put 方法生成缓存键,从数据库中检索并作为键值对放入缓存映射中。

public Object get(CdiRequest request) {
        Object cdiObject = cacheService.get(request.getContentElement()
                .getContentType(), keyBuilder.build(request));
        return cdiObject instanceof CdiResponse ? (CdiResponse) cdiObject
                : request;
}

//Put方法实现:

cacheService.put(cdiResponse.getCdiRequest().getContentElement()
                    .getContentType(),
                    keyBuilder.build(cdiResponse.getCdiRequest()), cdiResponse);

实现类:

 public class CacheService implements ApplicationContextAware{
    @Autowired
    private CacheManager cacheManager;
    private ApplicationContext applicationContext;

    public Object get(String applnName, Object key) {

            Cache  cache = cacheManager.getCache("contentCache");
            return cache.get(key);
      }

      public boolean put(String applnName, Object key, Object value) {
          Cache  cache =  cacheManager.getCache("contentCache");
          cache.put(key, value);
          return true;
      }
}

刷新或重新加载每个页面大约需要 60 到 80 秒,而 dynacache 只需要 3-4 秒。请告知是否有任何错误或可以以更好的方式完成。

【问题讨论】:

    标签: java spring spring-mvc caching ehcache


    【解决方案1】:

    为什么你不想在 Spring 中为 Cache 提供标准注解,并在从 DB 获取值的方法中使用它?:

    @Cacheable(value="contentCache", key="#name")
    

    所以您可以从数据库中获取内容并存储在缓存中?如果有变化,您可以使用CacheEvict

    【讨论】:

    • 如果我尝试像@Cacheable(value="contentCache") 那样会发生什么...你能告诉我在这种情况下key的意义吗
    • 你需要放钥匙。没有键,它会显示一个错误。
    • 我按照你提到的那样实现..没有键它没有向我显示任何错误..我仍然像这样对我的 dao 方法调用可缓存注释:@Cacheable(value="contentCache", key=" #name") 并尝试使用:@Cacheable(value="contentCache", key="#methodName") methodName - 生成我的自定义密钥.. 我在我的 dao 方法中有 sysout 来检查它是否打印甚至重新打印加载或刷新..它在每次页面加载或刷新时打印,这意味着它没有从内容缓存中获取..我还有什么错误吗?
    • 通过这个实现,我完全去掉了对cacheService的引用。我只有pom.xml、ehcache.xml和xml bean配置中的依赖项。正如我在之前的评论中提到的,我直接将此注释调用到我的 dao 方法中,该方法从我的数据库中检索内容
    【解决方案2】:

    有几点可以改进:

    1. 在配置级别
      • 您真的需要磁盘存储吗?由于必须对内容进行序列化/反序列化,因此会增加开销。
      • 如果您需要它,您需要将磁盘存储的大小设置为大于 onheap 的大小,因为所有映射都将存在于磁盘存储中。因此,使用当前配置,您实际上将 onheap 大小限制为 1000
    2. 在使用级别,您有效地将缓存用作内存存储,因为您没有逻辑来处理找不到映射的情况。现在,也许您正在缓存的是一组已知的键,并且小于您设置的大小。不过,这可能是后来出现问题的原因。

    关于性能问题,如果您需要帮助跟踪问题所在,则需要提供更详细的信息。

    【讨论】:

    • :非常感谢您的回复..我了解您的 pt..但是到目前为止..我们对 eh-cache 提供的配置很好..我能知道更详细的信息吗您需要跟踪问题..
    • 更多上下文:调用的代码、一些时间、表明缓存被有效使用的日志。简而言之,清除配置/设置问题的所有内容以及与缓存相关的调用的明确指示实际上一直在燃烧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    相关资源
    最近更新 更多