Micronaut升级至3.0.0后返回Flux.error出现无限请求问题
Micronaut 3.x 响应式接口无限挂起问题排查与解决
根因分析
从给出的日志可以看到,Reactor流只有onSubscribe和request(1)记录,没有onError或onComplete信号,说明流没有正常终止,导致请求一直挂起。该问题通常由异常未正确传播、Micronaut 配置缺失两类原因导致。
排查解决步骤
- 确认流内异常是否被捕获
在onErrorResume回调中增加日志,验证异常是否真的进入流的错误处理逻辑:
如果该日志未输出,说明@Override public Flux<List> freeTextSearch(String text) { return iProductManager.findFreeText(text).onErrorResume(throwable -> { // 新增日志确认回调触发 System.out.println("捕获到流内异常: " + throwable.getMessage()); return Flux.error(new GlobalException(throwable)); }); }findFreeText方法在组装流阶段就直接抛出异常(未进入流执行阶段),或返回的Flux本身未发送任何终止信号。- 确认流内异常是否被捕获
- 修复流组装阶段异常捕获逻辑
如果findFreeText方法在被调用时就直接抛出异常,需用Flux.defer包裹方法调用,确保组装阶段的异常也能被onErrorResume捕获:
@Override public Flux<List> freeTextSearch(String text) { // 用defer包裹,让方法调用在流订阅时才执行,异常会流入onErrorResume return Flux.defer(() -> iProductManager.findFreeText(text)) .onErrorResume(throwable -> Flux.error(new GlobalException(throwable))); }- 修复流组装阶段异常捕获逻辑
- 补充全局异常处理器的必要注解
Micronaut 3.x中响应式类型的异常处理器需要添加@Error注解才能生效,修改异常处理器代码:
@Produces @Singleton @Error // 新增该注解,Micronaut 3.x 要求异常处理器显式标注 @Requires(classes = {GlobalException.class, ExceptionHandler.class}) public class GlobalExceptionHandler implements ExceptionHandler<GlobalException, HttpResponse> { // 原有逻辑保持不变 }- 补充全局异常处理器的必要注解
- 统一接口与实现的返回值类型
你当前接口定义返回Flux<?>,实现类返回Flux<List>,类型不匹配可能导致Micronaut序列化层无法正确处理错误信号,统一返回值类型:
public interface IProductOperation { @Get(value = "/search/{text}") Flux<List> freeTextSearch(@NotBlank String text); // 把泛型?改成List和实现类对齐 }- 统一接口与实现的返回值类型
- 检查Reactor集成依赖
确认pom.xml或build.gradle中已引入和Micronaut版本匹配的micronaut-reactor依赖,3.x版本默认不会自动引入该依赖,缺失会导致Flux返回值无法被正确处理。
- 检查Reactor集成依赖
验证效果
修改完成后重新发起请求,预期流的error信号会正常传播,全局异常处理器被触发,接口返回500状态码,不会再无限挂起。
内容的提问来源于stack exchange,提问作者San Jaisy
相关产品推荐
相关产品推荐

