SpringBoot Web请求超时配置不生效,如何实现接口超时返回错误?
配置不生效的原因
server.tomcat.connection-timeout配置的是TCP连接建立阶段的超时时间,仅控制客户端和Tomcat三次握手建立连接的最大等待时长,和接口业务逻辑的执行时长无关。你的场景中连接已经正常建立,属于业务代码执行耗时过长,所以这个配置不会生效。spring.mvc.async.request-timeout配置的是Spring MVC异步请求的超时时间,仅对返回Callable、DeferredResult等异步返回值的接口生效。你当前写的是同步接口,Tomcat工作线程会同步阻塞等待业务逻辑执行完成,所以该配置不会触发超时。
实现接口超时返回的解决方案
方案1:改用异步接口(推荐,适配现有配置)
只需要调整Controller方法返回值为Callable即可,原有yml中spring.mvc.async.request-timeout配置会直接生效:
@RestController @RequestMapping("/test") public class TimeoutTest { @RequestMapping("/test") public Callable<String> test() { return () -> { try { System.out.println("start"); Thread.sleep(3000); System.out.println("end"); } catch (InterruptedException e) { e.printStackTrace(); } return "true"; }; } }
超时后会默认抛出AsyncRequestTimeoutException,你可以通过@ControllerAdvice全局捕获该异常,自定义返回的错误格式。
方案2:使用熔断组件控制超时
如果不想改异步接口,可以引入Resilience4j、Hystrix等熔断组件,通过注解指定方法超时时间:
以Resilience4j为例,引入对应依赖后,在接口方法上加@TimeLimiter注解即可:
@RestController @RequestMapping("/test") public class TimeoutTest { @TimeLimiter(name = "testTimeout", fallbackMethod = "timeoutFallback") @RequestMapping("/test") public CompletableFuture<String> test() { return CompletableFuture.supplyAsync(() -> { try { System.out.println("start"); Thread.sleep(3000); System.out.println("end"); } catch (InterruptedException e) { e.printStackTrace(); } return "true"; }); } // 超时降级方法 public CompletableFuture<String> timeoutFallback(Throwable t) { return CompletableFuture.completedFuture("接口请求超时"); } }
然后在yml中配置对应超时规则即可。
内容的提问来源于stack exchange,提问作者lincy_NY
相关产品推荐
相关产品推荐

