【问题标题】:Spring WebFlux with in memory cache带有内存缓存的 Spring WebFlux
【发布时间】:2020-09-09 13:05:26
【问题描述】:

我正在使用 Spring Web Flux 和 Guava 缓存。在某些示例中,他们使用 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。

【问题讨论】:

    标签: java spring guava spring-webflux


    【解决方案1】:

    您会看到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"));
    })
    

    【讨论】:

      猜你喜欢
      • 2020-08-09
      • 2011-07-08
      • 2018-03-15
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多