繁体   English   中英

Spring Cache拦截器

[英]Spring Cache interceptor

我们依靠一种系统来提供往往会经常出现故障的信息。 当前,我们使用hazelcast缓存条目,其有效期为1小时。 但是,这有一个问题,即缓存项被盲目驱逐,因此,如果系统不可用,请求将在一段时间内失败。

我正在寻找一种方法来拦截spring的缓存以添加逻辑,松散地说,我正在尝试从中修改内部spring调用。

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

没有高速缓存获取失败,因为“参考系统”不可用

如果您需要refreshAfterWrite的refreshAfterWrite,那么它是time-to-live-seconds

仅当您执行map.put操作时, time-to-live-seconds才会更改,因此与Guava的refreshAfterWrite设置基本相同。

请参阅: http : //docs.hazelcast.org/docs/3.8.6/manual/html-single/index.html#map-eviction

另外,您最有可能要在过期后刷新缓存中的数据。 然后,您可以使用MapLoader或接口。 http://docs.hazelcast.org/docs/3.8.6/manual/html-single/index.html#loading-and-storing-persistent-data

这样,当数据过期时,下一个调用将命中MapLoader.load方法,您可以从任何来源检查/获取新数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM