首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Spring Mono.retry反应代码中使用Mono.retry()实现重试机制

在Spring Mono.retry反应代码中使用Mono.retry()实现重试机制
EN

Stack Overflow用户
提问于 2022-09-25 04:16:45
回答 1查看 85关注 0票数 1

我正在使用Java 8和Spring调用一个基于REST的外部服务器,该服务器也有一个备份服务器。

当前,如果在调用服务器时出现故障,则会在没有重试机制的情况下访问备份服务器:

代码语言:javascript
复制
public class ServiceImpl {

    @Autowired
    MyRestClient myRestClient;

    @Autowired
    MyRestClient myRestClientBackup;

    public Mono<ResponseOutput> getResponseOutput(ResponseInput responseInput) {
        return Mono.just(responseInput)
            .flatMap(input -> {
                Mono<ResponseOutput> mono = myRestClient.post(input)
                    .doOnSuccess(responseOutput -> {
                        log.info("Successfully got responseOutput={}", responseOutput);
                    });
                return mono;
            })
            .onErrorResume(e -> {
                log.warn("Call to server failed, falling back to backup server...");
                Mono<ResponseOutput> mono = myRestClientBackup.post(responseInput)
                        .doOnSuccess(responseOutput ->
                                log.info("Successfully got backup responseOutput={}", responseOutput));
                return mono;
            });

    }
}

我正在尝试实现一种重试机制,在将numRetries属性设置为application.yml设置为特定数字时,应该会发生这样的情况:

例如,如果numRetries = 2

使用MyRestClient访问原始服务器两次(自numRetries = 2起),如果未能击中备份服务器。

它将numRetries配置属性设置为静态值:

application.yml

代码语言:javascript
复制
client:
   numRetries: 2;

application.yml文件加载配置属性的

代码语言:javascript
复制
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public ClientConfig {

    @Value("${client.numRetries:0}")
    private int numRetries;

    // Getters and setters omitted for brevity
}

ClientConfigMyRestClient使用

代码语言:javascript
复制
public class MyRestClient {

    @Autowired 
    ClientConfig   config;

    // Getters and setters omitted for brevity
}

在从numRetries获得MyRestClient值后,如何在调用备份服务器之前更改ServiceImpl.getResponseOutput()中的原始实现以使用numRetries访问原始服务器?正如您所看到的,这都是最初使用Java 8、lambda和streams完成的.

找到这个注释@Retryable(value = RestClientException.class),但不知道如何指定else if numRetries is used to call the backup server (伪代码)?

是否有一个lambda函数来表示要使用的numRetries

代码语言:javascript
复制
return Mono.just(responseInput)
            .flatMap(input -> {

如何使用Mono.retry()操作符?

而且,这段代码中的reactor版本似乎已经不推荐Mono.retry().retryBackOff()方法了?

如何使用引用numRetries的值(这将是一个int)来命令继续重试(失败时),然后当numRetries被超越时,.onErrorResume()来调用另一个备份服务器?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-25 18:15:22

使用retry(int)运算符来自Mono,如下所示:

代码语言:javascript
复制
Mono.just(responseInput)
    .flatMap(input -> myRestClient.post(input)
        .retry(getNumRetries()) // this is the important part
        .doOnSuccess(responseOutput -> log.info("Successfully got responseOutput={}", responseOutput)))
    .onErrorResume(e -> {
        log.warn("Call to server failed, falling back to backup server...");
        return myRestClientBackup.post(responseInput)
            .doOnSuccess(responseOutput -> log.info("Successfully got backup responseOutput={}", responseOutput));
    });
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73842022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档