如何在Spring Boot REST API上设置超时?

2022-09-03 16:13:05

我有一些 REST API 可能需要一段时间才能执行,并且我想限制它们的执行持续时间。最好,如果30秒过去了并且请求没有返回,我想返回特定的HTTP代码/数据并完全终止该请求。

当前代码:

@RestController
@CrossOrigin(origins = {"*"}, maxAge = 4800, allowCredentials = "false")
public class APIController {

@RequestMapping(value = "/api/myapifunc", method = RequestMethod.POST, produces = "application/json")
public ResponseEntity<?> optimize(@RequestParam(value="param1", defaultValue="")) {
    // Code here
}

答案 1

看起来您正在描述断路器模式。如果您同时可以控制客户端和服务器代码,并希望探索Spring Cloud和Netflix Hysterix库,则可以查看入门:断路器指南。

如果您使用Apache Tomcat作为您的servlet容器,您可以配置卡住的线程检测阀

此阀允许检测需要很长时间才能处理的请求,这可能表示正在处理它的线程已卡住。此外,它还可以选择中断此类线程以尝试并取消阻止它们。

当检测到这样的请求时,其线程的当前堆栈跟踪将写入具有WARN级别的Tomcat日志。

卡住线程的 ID 和名称可通过 JMX 在 stuckThreadIds 和 stuckThreadNames 属性中获得。这些 ID 可以与标准的 Threading JVM MBean (java.lang:type=Threading) 一起使用,以检索有关每个卡住的线程的其他信息。


答案 2

使用Spring Boot 2.3 / Tomcat 9,您可以通过安装Tomcat来设置所有传入HTTP请求的超时。以下是您需要的Spring配置代码(它是Kotlin):StuckThreadDetectionValve

import org.apache.catalina.valves.StuckThreadDetectionValve
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class RequestTimeoutConfiguration(
    @Value("\${app.tomcat.stuck-thread-detection.request-timeout.seconds}")
    private val stuckThreadTimeoutSeconds: Int
) {

    @Bean
    fun stuckThreadDetectionValve() =
        StuckThreadDetectionValve().apply {
            threshold = stuckThreadTimeoutSeconds
            interruptThreadThreshold = stuckThreadTimeoutSeconds
        }

    @Bean
    fun stuckThreadDetectionWebServerFactoryCustomizer(valve: StuckThreadDetectionValve) =
        WebServerFactoryCustomizer { factory: TomcatServletWebServerFactory ->
            factory.addContextValves(valve)
        }
}

然后,您只需要 in 中的属性来控制它:application.properties

app.tomcat.stuck-thread-detection.request-timeout.seconds=130

推荐