如何在处理Mono时主动抛出异常以触发重试?
问题分析
你当前代码的核心问题有两个:一是用doOnNext(副作用操作符)做校验抛异常,不符合Reactor的数据流设计规范;二是onErrorResume用法错误——它需要返回Mono类型的错误信号,而非直接抛出异常。另外,doOnNext里的异常虽会触发错误信号,但后续处理逻辑没正确承接,导致重试不生效。
可行解决方案
1. 用map替代doOnNext实现校验
map是转换类操作符,会直接参与数据流处理,抛出的异常会自动转为onError信号,能被下游重试机制捕获:
public Mono<Response> handleResponse() { return userService.getUser() .map(response -> { validate(response.getData()); return response; }); } private void validate(Data data) { // 校验逻辑示例 if (data == null || data.getId() <= 0) { throw new RuntimeException("数据校验失败"); } }
这里无需额外的onErrorResume,map抛出的异常会直接进入错误流,触发重试。
2. 用handle操作符灵活控制错误信号
handle支持同时处理正常元素和错误场景,适合复杂校验逻辑:
public Mono<Response> handleResponse() { return userService.getUser() .handle((response, sink) -> { try { validate(response.getData()); sink.next(response); } catch (RuntimeException e) { sink.error(e); } }); }
通过sink.error(e)主动发送错误信号,确保下游能捕获并触发重试。
3. 配合@Retryable的正确姿势
如果你用Spring Retry的@Retryable注解,需要注意两点:
- 必须在配置类上添加
@EnableRetry开启重试功能; - 确保标注
@Retryable的方法是被Spring代理的——也就是通过Spring容器调用该方法,不能用类内部的this直接调用,否则代理不生效,重试逻辑不会触发。
4. 除Mono自身重试外的替代方案
编程式Spring Retry
如果注解方式不满足需求,可直接用RetryTemplate实现编程式重试:
@Autowired private RetryTemplate retryTemplate; public Mono<Response> handleResponse() { return Mono.fromCallable(() -> retryTemplate.execute(context -> userService.getUser() .map(response -> { validate(response.getData()); return response; }) .block() // 仅在RetryTemplate内部同步调用,对外仍返回非阻塞Mono ) ); }
自定义重试操作符封装
可以封装通用的重试逻辑,结合repeatWhen实现基于错误类型和次数的重试:
public <T> Mono<T> withCustomRetry(Mono<T> mono) { return mono.repeatWhen(repeatSignal -> repeatSignal .zipWith(Flux.range(1, 3)) // 最多重试3次 .flatMap(tuple -> { Throwable error = tuple.getT1(); int attempt = tuple.getT2(); if (error instanceof RuntimeException && attempt <= 3) { return Mono.delay(Duration.ofSeconds(1)); // 每次重试间隔1秒 } return Mono.error(error); }) ); } // 使用示例 public Mono<Response> handleResponse() { return withCustomRetry( userService.getUser() .map(response -> { validate(response.getData()); return response; }) ); }
内容的提问来源于stack exchange,提问作者Mihan
相关产品推荐
相关产品推荐

