我們依賴一個系統來提供往往經常關閉的信息。目前我們使用hazelcast緩存1小時到期策略的條目。但是,這有一個問題,即緩存條目被盲目驅逐,因此如果系統不可用,請求將會失敗一段時間。Spring Cache攔截器
我正在尋找一種方式來攔截春天的緩存添加邏輯,嚴格意義上,我試圖從
Object valueFromCache = cache.getValue(cacheKey);
if (null == valueFromCache) {
valueFromCache = cachedMethod.invokeMethod();
cache.putValue(cacheKey, valueFromCache);
}
return valueFromCache;
修改內部彈簧調用到
Object valueFromCache = cache.getValue(cacheKey);
if (null == valueFromCache) {
valueFromCache = cachedMethod.invokeMethod();
cache.putValue(cacheKey, valueFromCache);
} else if (isValueExpired(valueFromCache)) {
try {
valueFromCache = cacheMethod.invokeMethod();
cache.putValue(cacheKey, valueFromCache);
} catch (FailedToRefreshDataException ex) {
doWhateverWithException(ex);
}
}
return valueFromCache;
基本上,我不想讓底層緩存提供者(在我的例子中爲hazelcast)決定何時驅逐條目,但只有在獲取新值時才應用該應用。
我們可以處理稍微陳舊的數據以獲得更高可用性的風險。
編輯: 我想要的東西,功能類似於番石榴cachebuilder的refreshAfterWrite
例如
public static void main(String[] args) throws ExecutionException, InterruptedException {
AtomicInteger atomicInteger = new AtomicInteger();
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.refreshAfterWrite(100, MILLISECONDS)
.build(new CacheLoader<String, String>() {
@Override
public String load(String value) throws Exception {
int intValue = atomicInteger.incrementAndGet();
if (intValue % 2 == 0) {
throw new IllegalStateException("Failed to whatever");
}
return value + intValue;
}
});
for (int i = 0; i < 10; i++) {
System.out.println("Attempt " + i + "=" + cache.get("Shoes"));
Thread.sleep(50);
}
}
輸出
Attempt 0=Shoes1
Attempt 1=Shoes1
Attempt 2=Shoes1
Attempt 3=Shoes3
Attempt 4=Shoes3
Attempt 5=Shoes3
Attempt 6=Shoes5
Attempt 7=Shoes5
Attempt 8=Shoes5
Attempt 9=Shoes7
無緩存下載失敗,因爲 '參考系統' 是不可用
time-to-live-seconds並不是我正在尋找的,正如我的問題描述的第一句中提到的那樣。我不希望條目被盲目驅逐,我希望只有在有新版本可用時才能替換條目。 – Alexandru
@Alexandru我剛剛使用'MapLoader'更新了我的答案,就像Guava CacheLoader一樣,但有更多選項。 –