Spring 带有内存缓存的 WebFlux
Spring WebFlux with in memory cache
我正在使用 Spring 网络通量和番石榴缓存。在某些示例中,他们使用 CacheMono.lookup 从缓存中检索值。我在同一行上试过并有以下代码。
CacheMono.lookup(key -> Mono.justOrEmpty(guavaCache.get(id, PhoneNumber.class))
.map(Signal::next), id)
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id);})
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> {
if(value == null){
LOGGER.info("value is null");
}
LOGGER.info("value is not null "+value);
guavaCache.put(key, value);}))))
对于当 guava 缓存不包含它从 db 获取并存储到缓存中的值时的初始流程。但是对于同一个键,当我再次发送请求时,缓存中有该键的值。但是 CacheMono.lookup 仍在执行从 db ( I am seeing LOGGER.info("fetch from db");.
获取数据,但同时我没有看到日志 LOGGER.info("value is not null "+value);
我对这种行为感到困惑。为什么onCacheMissResume在缓存已经有数据的情况下被调用了2次
您看到 LOGGER.info("fetch from db")
因为每次 CacheMono
创建 Mono<PhoneNumber>
从数据库中获取时都会调用它。但是如果该值存在于您的缓存中,则此 Mono<PhoneNumber>
将不会被订阅。
您可以通过记录 onSubscribe
事件来检查它:
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id)
.doOnSubscribe(ignored -> LOGGER.info("really fetching from db"));
})
我正在使用 Spring 网络通量和番石榴缓存。在某些示例中,他们使用 CacheMono.lookup 从缓存中检索值。我在同一行上试过并有以下代码。
CacheMono.lookup(key -> Mono.justOrEmpty(guavaCache.get(id, PhoneNumber.class))
.map(Signal::next), id)
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id);})
.andWriteWith((key, signal) -> Mono.fromRunnable(() ->
Optional.ofNullable(signal.get())
.ifPresent(value -> {
if(value == null){
LOGGER.info("value is null");
}
LOGGER.info("value is not null "+value);
guavaCache.put(key, value);}))))
对于当 guava 缓存不包含它从 db 获取并存储到缓存中的值时的初始流程。但是对于同一个键,当我再次发送请求时,缓存中有该键的值。但是 CacheMono.lookup 仍在执行从 db ( I am seeing LOGGER.info("fetch from db");.
获取数据,但同时我没有看到日志 LOGGER.info("value is not null "+value);
我对这种行为感到困惑。为什么onCacheMissResume在缓存已经有数据的情况下被调用了2次
您看到 LOGGER.info("fetch from db")
因为每次 CacheMono
创建 Mono<PhoneNumber>
从数据库中获取时都会调用它。但是如果该值存在于您的缓存中,则此 Mono<PhoneNumber>
将不会被订阅。
您可以通过记录 onSubscribe
事件来检查它:
.onCacheMissResume(() -> {
LOGGER.info("fetch from db");
return phoneNumberRepository.findById(id)
.doOnSubscribe(ignored -> LOGGER.info("really fetching from db"));
})