我正在使用 LoadingCache:
val cacheloader =
new CacheLoader[Key, Value]() {
override def load(key: Key): Value = loadKeyFunc(key, None)
override def reload(key: Key, prevValue: Value): ListenableFuture[Value] = {
val task = ListenableFutureTask.create(new Callable[Value]() {
def call(): Value = {
loadKeyFunc(key, Some(prevValue))
}
})
executor.execute(task)
return task
}
}
val cache: LoadingCache[FirstPageSearch, Array[String]] =
CacheBuilder.newBuilder()
.maximumSize(10)
.refreshAfterWrite(5, TimeUnit.MINUTES)
.build(cacheLoader)
loadKeyFunc
只是表单的匿名函数val loadKeyFunc: (Key, Option[Value]) => Value
。cacheLoader 使用 executor ( Executors.newFixedThreadPool(6)
) 使刷新异步。系统收到一个始终通过此缓存的 HTTP 请求(get(key)
向缓存发出 a),始终从缓存中获取结果。当它太旧时,它会在后台重新计算并在下一个请求时提供它。
几天甚至几周内一切正常。但有时(通常在非常低的使用时间)缓存会停止刷新。新请求开始接收总是相同的旧数据。我里面有一个日志语句loadKeyFunc
,我知道它没有被调用。
似乎由于某种原因LoadingCache
没有看到数据超过 5 分钟。在我重新启动系统(HTTP 服务器)后,一切又恢复正常。
有任何想法吗?
PS:我们使用的 loadKeyFunc 只是一个简单的日志语句,然后调用一个无状态对象,该对象查询我们的搜索后端系统返回一个字符串数组(每个数组位置都是一个搜索页面)。
PS2:它是一个基于 Scalatra 的运行嵌入式 Jetty HTTP 服务器。LoadingCache
是在对象内部创建的ScalatraServlet
。
清理后的小日志(/first_page 是始终使用缓存的请求,“Executing...”是 (re)load 方法中的日志语句CacheLoader
):
[INFO] [qtp48202314-8659] 2012-11-03 04:55:58 - Request(/first_page)
[INFO] [pool-2-thread-10] 2012-11-03 04:55:58 - Executing FirstPageSearch to put in cache
[INFO] [qtp48202314-8659] 2012-11-03 05:19:17 - Request(/first_page)
[INFO] [qtp48202314-8659] 2012-11-03 05:20:32 - Request(/first_page)
[INFO] [qtp48202314-8661] 2012-11-03 05:25:22 - Request(/first_page)
[INFO] [qtp48202314-8659] 2012-11-03 05:26:09 - Request(/first_page)
[INFO] [qtp48202314-8659] 2012-11-03 05:26:18 - Request(/first_page)
[INFO] [qtp48202314-8661] 2012-11-03 05:38:37 - Request(/first_page)
[INFO] [qtp48202314-8659] 2012-11-03 06:54:36 - Request(/first_page)
[INFO] [qtp48202314-26] 2012-11-03 11:31:37 - Request(/first_page)
[INFO] [pool-2-thread-1] 2012-11-03 11:31:37 - Executing FirstPageSearch to put in cache
[INFO] [qtp48202314-25] 2012-11-03 11:41:53 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 14:48:58 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 14:54:45 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 15:31:32 - Request(/first_page)
[INFO] [qtp48202314-26] 2012-11-03 15:31:48 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 15:32:05 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 15:44:44 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 15:44:44 - Request(/first_page)
[INFO] [qtp48202314-26] 2012-11-03 15:47:39 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 15:51:20 - Request(/first_page)
[INFO] [qtp48202314-26] 2012-11-03 15:52:59 - Request(/first_page)
[INFO] [qtp48202314-8674] 2012-11-03 15:54:18 - Request(/first_page)
[INFO] [qtp48202314-26] 2012-11-03 15:55:37 - Request(/first_page)