Spring 反应器 Retry.retryWhen() 没有工作
Spring Reactor Retry.retryWhen() did not work
如何使用重试?
我想在错误时重试调用方法,直到成功为止。
我的测试代码
@Test
public void fun1() throws InterruptedException {
this.generate()
.retryWhen(Retry.fixedDelay(5, Duration.ofMillis(1))
.filter(e -> e instanceof Exception)
.doBeforeRetry(res -> System.out.println("retry begin"))
.doAfterRetry(res -> System.out.println("try finished")))
.onErrorContinue((throwable, o) -> System.out.println(throwable))
.subscribe(System.out::println);
}
private Mono<String> generate() throws InterruptedException {
if (retryTime.get() == 3) {
return Mono.just("Hello");
}
System.out.println("i am called" + retryTime.getAndAdd(1));
return Mono.error(new IllegalArgumentException("exception test"));
}
** 但得到这个结果**
i am called1
10:02:12.104 [main] DEBUG reactor.util.Loggers - Using Slf4j logging framework
retry begin
try finished
retry begin
try finished
retry begin
try finished
retry begin
try finished
retry begin
try finished
reactor.core.Exceptions$RetryExhaustedException: Retries exhausted: 5/5
Process finished with exit code 0
为什么不重试3次直到成功???
通过重新订阅 上游方法的结果进行重试。它不会重新调用上游方法。
在您的具体情况下,来自 .retryWhen
的每个订阅都订阅从对 generate()
的单次调用返回的 Mono.error
。因此,每个订阅看到相同的异常结果。
要解决此问题,您需要将 generate()
方法中的逻辑延迟到 subscription 时间,而不是 assembly[=31] =]时间。
例如,使用Mono.fromCallable
,像这样:
private Mono<String> generate() {
return Mono.fromCallable(() -> {
if (retryTime.get() == 3) {
return "Hello";
}
System.out.println("i am called" + retryTime.getAndAdd(1));
throw new new IllegalArgumentException("exception test");
});
}
将为每个订阅者调用 Callable。具体来说,每次 retryWhen
运营商重新订阅时都会调用它。
如何使用重试? 我想在错误时重试调用方法,直到成功为止。 我的测试代码
@Test
public void fun1() throws InterruptedException {
this.generate()
.retryWhen(Retry.fixedDelay(5, Duration.ofMillis(1))
.filter(e -> e instanceof Exception)
.doBeforeRetry(res -> System.out.println("retry begin"))
.doAfterRetry(res -> System.out.println("try finished")))
.onErrorContinue((throwable, o) -> System.out.println(throwable))
.subscribe(System.out::println);
}
private Mono<String> generate() throws InterruptedException {
if (retryTime.get() == 3) {
return Mono.just("Hello");
}
System.out.println("i am called" + retryTime.getAndAdd(1));
return Mono.error(new IllegalArgumentException("exception test"));
}
** 但得到这个结果**
i am called1
10:02:12.104 [main] DEBUG reactor.util.Loggers - Using Slf4j logging framework
retry begin
try finished
retry begin
try finished
retry begin
try finished
retry begin
try finished
retry begin
try finished
reactor.core.Exceptions$RetryExhaustedException: Retries exhausted: 5/5
Process finished with exit code 0
为什么不重试3次直到成功???
通过重新订阅 上游方法的结果进行重试。它不会重新调用上游方法。
在您的具体情况下,来自 .retryWhen
的每个订阅都订阅从对 generate()
的单次调用返回的 Mono.error
。因此,每个订阅看到相同的异常结果。
要解决此问题,您需要将 generate()
方法中的逻辑延迟到 subscription 时间,而不是 assembly[=31] =]时间。
例如,使用Mono.fromCallable
,像这样:
private Mono<String> generate() {
return Mono.fromCallable(() -> {
if (retryTime.get() == 3) {
return "Hello";
}
System.out.println("i am called" + retryTime.getAndAdd(1));
throw new new IllegalArgumentException("exception test");
});
}
将为每个订阅者调用 Callable。具体来说,每次 retryWhen
运营商重新订阅时都会调用它。