【问题标题】:grails 2.4.2 ehcache plugin 1.0.5 evicts keys prematurelygrails 2.4.2 ehcache 插件 1.0.5 过早地驱逐密钥
【发布时间】:2017-08-04 00:12:45
【问题描述】:

使用 grails 2.4.2、cache:1.1.8 和 cache-ehcache:1.0.5,我发现缓存只包含一个条目。一旦添加第二个条目,第一个条目就会消失。

配置

BuildConfig.groovy:

compile ":cache:1.1.8"
compile ":cache-ehcache:1.0.5"

Config.groovy:

grails.hibernate.cache.queries = true

grails {
  cache {
    order = 2000
    enabled = true
    clearAtStartup = true
    shared = true
    ehcache {
      reloadable = false
    }
  }
}

grails.cache.clearAtStartup = true

grails.cache.config = {
  cache {
    name 'siteSettings'
  }
  provider {
    updateCheck false
    monitoring 'on'
    dynamicConfig false
  }
  defaultCache {
    maxElementsInMemory 10000
    timeToIdleSeconds 600
    timeToLiveSeconds 600
    overflowToDisk false
    diskPersistent false
    memoryStoreEvictionPolicy 'LRU'
  }
  defaults {
    maxElementsInMemory 10000
    timeToIdleSeconds 600
    timeToLiveSeconds 600
    overflowToDisk false
    diskPersistent false
    memoryStoreEvictionPolicy 'LRU'
  }
}

SettingsService.groovy 中的缓存方法:

@Cacheable(value='siteSettings')
public JSONElement getSiteSettings(Integer site){
  log.info "NOT CACHED for this request (${site})"

日志输出

1) site=229 的第一个请求(没有缓存):

    Initialised cache: siteSettings
    CacheDecoratorFactory not configured for defaultCache. Skipping for 'siteSettings'.
    siteSettings size: 0
    cacheKeys: 0
    NOT CACHED for this request (229)
    put at siteSettings: [ key = grails.plugin.cache.CustomCacheKeyGenerator$CacheKey@490f0efa, value={"test":229}, version=1, hitCount=3, CreationTime = 1489534645017, LastAccessTime = 1489534976819 ]

2) site=229 的第二个请求(缓存保存 229):

    siteSettings size: 1
    cacheKeys: 1
    key 229: [test:229]

3) site=282 的第一个请求(缓存保存 229):

    siteSettings size: 1
    cacheKeys: 1
    key 229: [test:229]
    NOT CACHED for this request (282)
    evicted from siteSettings: [ key = grails.plugin.cache.CustomCacheKeyGenerator$CacheKey@490f0efa, value={"test":229}, version=1, hitCount=3, CreationTime = 1489534645017, LastAccessTime = 1489534976819 ]
    put at siteSettings: [ key = grails.plugin.cache.CustomCacheKeyGenerator$CacheKey@492726a5, value={"test":282}, version=1, hitCount=0, CreationTime = 1489534976848, LastAccessTime = 1489534976848 ]

4) site=282 的第二个请求(缓存保存 282,而不是 229):

    siteSettings size: 1
    cacheKeys: 1
    key 282: [test:282]

5) site=229 的第三个请求(缓存保存 282,而不是 229):

    siteSettings size: 1
    cacheKeys: 1
    key 282: [test:282]
    NOT CACHED for this request (229)
    evicted from siteSettings: [ key = grails.plugin.cache.CustomCacheKeyGenerator$CacheKey@492726a5, value={"test":282}, version=1, hitCount=3, CreationTime = 1489534976848, LastAccessTime = 1489535172110 ]
    put at siteSettings: [ key = grails.plugin.cache.CustomCacheKeyGenerator$CacheKey@490f0efa, value={"test":229}, version=1, hitCount=0, CreationTime = 1489535172193, LastAccessTime = 1489535172193 ]

分析

  1. 在 site=229 的第一个请求中,没有缓存任何内容。正如预期的那样

  2. 在 site=229 的第二个请求中,以 229 为关键字的条目被缓存。正如预期的那样

  3. 在 site=282 的第一个请求中,以 229 为键的条目被缓存,但以 282 为键的条目未被缓存。正如预期的那样

  4. 在 site=282 的第二个请求中,282 键上的条目被缓存,但 229 键上的条目不再被缓存。 UNEXPECTED - 期望两个键都被缓存。

  5. 在 site=229 的第三个请求中,282 键上的条目仍被缓存,但 229 键上的条目未被缓存。 UNEXPECTED - 期望两个键都被缓存(随后,282 被驱逐,而 229 被放置,这与观察到的行为相匹配)

我做错了什么?感谢您的帮助。

【问题讨论】:

  • 您从哪里获取 siteSettings、cacheKeys 和键 ... 日志记录语句?你能在 Ehcache 上添加一个缓存事件监听器,看看你是否有效地获得了驱逐吗?
  • 我实现了一个 CacheEventListener 并将输出添加到我的原始帖子中。它似乎验证了我的怀疑:每次将一个条目添加到缓存中时,前一个条目都会被逐出。
  • 为了回答您问题的第一部分,Louis,日志记录语句源自调用可缓存 grails 服务方法的 grails 控制器操作。

标签: caching grails ehcache


【解决方案1】:

正如我所怀疑的那样,配置有问题。为了让 grails.plugin.cache.ConfigLoader 识别出您在 Config.groovy 中的 grails.cache 声明是一个闭包,必须有一个等号 (=),如下所示:

Config.groovy:

// wrong
grails {
  cache {
    order = 2000
    enabled = true
    clearAtStartup = true
    shared = true
    ehcache {
      reloadable = false
    }
  }
}

// right
grails {
  cache = {
    order = 2000
    enabled = true
    clearAtStartup = true
    shared = true
    ehcache {
      reloadable = false
    }
  }
}

很遗憾,http://grails-plugins.github.io/grails-cache-ehcache/guide/usage.html 的文档中没有反映这一点,该文档显示了一个不带等号的配​​置元素示例。

我在将 grails.plugin.cache 日志级别设置为“调试”后发现了这一点,此时日志输出出现:

DEBUG ehcache.EhcacheConfigLoader  - Not including configs from Config.groovy

检查 EhcacheConfigLoader 的源代码表明,当 cache.config 设置不是闭包时会出现此错误消息。在配置中添加等号使其成为一个闭包,并且来自 Config.groovy 的缓存配置现在已加载,这似乎解决了问题。

【讨论】:

  • 不幸的是,添加的等号导致 grails 单元测试因以下错误而中断:Fatal error running tests: No signature of method: grails.plugin.cache.ehcache.EhcacheConfigLoader.processConfig() is applicable for argument types: (Config$_run_closure2_closure10, null) values: [Config$_run_closure2_closure10@283eea2a, null]。删除等号后,单元测试可以正常工作。
  • 已通过禁用 Config.groovy 中“测试”环境的所有缓存相关配置来修复:if (!Environment.current.equals(Environment.TEST)) {...
【解决方案2】:

我很抱歉,但这整个线程结果是基于一个错误。通过从 grails 外部配置 .properties 文件中删除似乎掩盖了 Config.groovy 中 grails.cache.config 的正确定义的行,解决了根本问题。外部配置是:

grails.cache.config.defaultCache.diskStore='java.io.tmpdir'

在 grails.cache 声明中添加等号的建议修复不正确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 2013-10-18
    • 2013-04-23
    • 2014-08-20
    • 2016-10-08
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多