【问题标题】:Implement Webclient Mono Caching实施 Webclient Mono 缓存
【发布时间】:2023-02-13 15:50:07
【问题描述】:

我已经使用带有 Spring Cache 和 EhCache 实现的 spring mvc 应用程序实现了缓存,我在其中配置了 (.xml) 键类型和值类型,如下所示

    <key-type>java.lang.String</key-type>
    <value-type>my.object.returned</value-type>

但是现在我正在开发一个 Spring Webflux 应用程序,我正在调用第 3 方 API(Web 客户端调用)来获取一些数据。

为从 Webclient 返回的 Mono/Flux 数据实现缓存(在内存中)的最佳方法是什么。保留任何 Spring 缓存策略或 Project Reator 有一些本机缓存策略?

谢谢,

【问题讨论】:

    标签: caching spring-webflux


    【解决方案1】:

    事实上,我有一个调用外部 API 的服务方法。

    Mono<String> getExternalData (String input, ENUM enum) 
    
        Webclient.get
        ...
    
    1. 我需要为相同的输入键(字符串、枚举)缓存结果值
    2. 我想访问代码另一部分(缓存管理器)中的缓存值,以便在其他上下文中使用它。

    【讨论】:

    • 您甚至阅读并尝试过我的回答吗?
    • 是的,我已经读过……感谢您的宝贵时间。我只是更新了你质疑的细节,你回答了。我正在研究解决方案。谢谢
    【解决方案2】:

    您没有提供有关要缓存的内容的任何详细信息。基本上反应堆有多种.cache()方法用于缓存不同的策略。当您需要获取某些 API 的访问令牌并使用此令牌调用该 API 时,我将为您提供一些场景示例。比方说,这个令牌已经过期了,我们想缓存它并在它过期后刷新。

    /**
     * Creating cached token mono
    */
    Mono<Token> tokenMono = authenticate();
    
    /**
     * Flow for calling mock api with cached token
     * Mock api called every 3 seconds with token. Token is valid for 10 seconds
     * Token will be refreshed after it is expired
     */
    @Test
    public void cacheCallTest() {
        Flux.interval(Duration.ofSeconds(3L))
                .flatMap(__ -> tokenMono)
                .flatMap(this::makeCall)
                .doOnNext(log::info)
                .blockLast();
    }
    
    /**
     * Mock auth api that returns cached token that will be cached until it is not expired
     * You can setup your caching strategy with .cache() methods, customize it with Duration and etc.
     */
    public Mono<Token> authenticate() {
        return getToken()
                .cacheInvalidateIf(token ->
                        Instant.now().isAfter(token.validUntil)
                );
    }
    
    /**
     * Token supplier
     */
    public Mono<Token> getToken() {
        return Mono.fromSupplier(() -> {
            Instant validUntil = Instant.now().plus(10, ChronoUnit.SECONDS);
            return new Token("token " + validUntil, validUntil);
        });
    }
    
    /**
     * Call mock api with the given token
     * @param token token
     */
    public Mono<String> makeCall(Token token) {
        log.info("Making call with token {}", token.getToken());
        return Mono.defer(() -> Mono.just("Responded at  " + Instant.now()));
    }
    
    @Data
    @AllArgsConstructor
    public static class Token {
    
        private String token;
        private Instant validUntil;
    }
    

    这将弹出以下结果:

    02:55:46.723 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:55:56.710578Z
    02:55:46.729 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:55:46.728161Z
    02:55:49.704 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:55:56.710578Z
    02:55:49.705 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:55:49.705182Z
    02:55:52.706 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:55:56.710578Z
    02:55:52.706 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:55:52.706181Z
    02:55:55.704 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:55:56.710578Z
    02:55:55.705 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:55:55.705420Z
    02:55:58.711 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:56:08.711051Z
    02:55:58.711 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:55:58.711654Z
    02:56:01.702 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:56:08.711051Z
    02:56:01.703 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:56:01.703090Z
    02:56:04.706 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:56:08.711051Z
    02:56:04.707 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:56:04.706760Z
    02:56:07.705 [parallel-1] INFO com.example.demo.FluxTest - Making call with token token 2023-01-22T22:56:08.711051Z
    02:56:07.706 [parallel-1] INFO com.example.demo.FluxTest - Responded at  2023-01-22T22:56:07.706292Z
    

    调用时注意token的时间戳。 希望能帮助到你。

    【讨论】:

      猜你喜欢
      • 2012-08-06
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      相关资源
      最近更新 更多