Spring Cloud Gateway调用OAuth加JWT头时block()阻塞报错如何解决
问题原因
你当前使用的Spring Cloud Gateway是基于WebFlux的响应式框架,所有请求处理逻辑都运行在非阻塞IO线程上,block() 是同步阻塞等待响应结果的方法,会占用IO线程违反响应式非阻塞设计规范,因此框架直接抛出异常禁止此类调用。
解决方法
你不需要修改业务服务的代码,只需要调整网关过滤器的实现逻辑,通过响应式操作符串联整个处理流程,避免阻塞调用即可:
@Autowired private IConsumoInstrospectService consumoIntrospect; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return consumoIntrospect .callInstrospect("firmaCnLlavePrivada", "getAccessToken()","getScope()", "IN") // 异步非阻塞获取OAuth接口返回结果 .flatMap(responseIntrospectDTO -> { String token = responseIntrospectDTO.getJwt(); log.info("token {}", token); String authHeader = "Bearer " + token; // 修改请求头 ServerHttpRequest mutatedRequest = exchange.getRequest().mutate() .header(HttpHeaders.AUTHORIZATION, authHeader) .build(); ServerWebExchange mutatedExchange = exchange.mutate().request(mutatedRequest).build(); // 继续执行后续过滤器链,完成请求转发 return chain.filter(mutatedExchange); }) // 可选:添加异常处理,调用OAuth接口失败时直接返回错误 .onErrorResume(e -> { log.error("调用OAuth接口获取JWT失败", e); exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); }); }
逻辑说明
调整后的代码全程保持异步非阻塞:callInstrospect 方法返回的Mono对象会在OAuth接口有返回结果时,自动触发flatMap里的逻辑修改请求头,再将修改后的请求交给后续过滤器链转发,全程不会阻塞IO线程,完全符合WebFlux的设计要求。
内容的提问来源于stack exchange,提问作者Omar Barrera Valentin
相关产品推荐
相关产品推荐

