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)
) を使用して更新を非同期にします。システムは、常にこのキャッシュを通過する (キャッシュに aget(key)
を発行する) HTTP 要求を受信し、常にキャッシュから結果をフェッチします。古すぎる場合は、バックグラウンドで再計算し、次のリクエストで提供します。
数日、場合によっては数週間、すべてが正常に機能します。しかし、ときどき (通常、使用量が非常に少ない時間帯に) キャッシュの更新が停止します。新しいリクエストは常に同じ古いデータを受け取り始めます。内部にログ ステートメントがloadKeyFunc
あり、それが呼び出されていないことがわかっています。
何らかの理由LoadingCache
で、データが 5 分よりもかなり古いことが表示されていないようです。システム (HTTP サーバー) を再起動すると、すべて正常に戻ります。
何か案は?
PS: 使用する loadKeyFunc は単純なログ ステートメントの後に、検索バックエンド システムにクエリを実行して String 配列を返すステートレス オブジェクトへの呼び出しが続きます (各配列位置は検索ページです)。
PS2: 組み込みの Jetty HTTP サーバーを実行する Scalatra ベースです。はオブジェクトLoadingCache
内に作成されScalatraServlet
ます。
クリーンアップされた小さなログ (/first_page は常にキャッシュを使用する要求であり、"Executing..." は の (再) ロード メソッド内のログ ステートメントです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)