Spring-server.connection-timeout 不工作

新手上路,请多包涵

在我的 application.properties 文件中我有…

 server.port=8086
server.connection-timeout=15000

我知道文件正在正确加载,因为服务器正在端口 8086 上运行。

在应用程序中我有一个 RestController

 @RestController
class TestController {
    @GetMapping()
    fun getValues(): ResponseEntity<*> {
        return someLongRunningProcessPossiblyHanging()
    }
}

当我调用端点时,请求永远不会超时,它只是无限期地挂起。

我错过了什么吗?

注意: 我还被告知 Tomcat 在几分钟内使用此字段,而不是几毫秒(IMO 的不寻常选择)。我尝试将其设置为 server.connection-timeout=1 表示 1 分钟,但这也不起作用。

注意: 我不希望 另一个 HTTP 请求导致先前的请求超时,我希望每个 HTTP 请求都自动超时,如果时间过长无法满足请求。

原文由 Matthew Layton 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2k
2 个回答

connection-timeout 不适用于长时间运行的请求。它确实适用于初始连接,当服务器等待客户端说些什么时。

Tomcat 文档(不是 Spring Boot)将其定义 为此连接器在接受连接后等待显示请求 URI 行的毫秒数 […]

要测试设置 server.connection-timeout=4000 我使用 netcat 连接,我不发送任何 HTTP 请求/标头。我得到:

 $ time nc -vv localhost 1234
Connection to localhost 1234 port [tcp/*] succeeded!

real    0m4.015s
user    0m0.000s
sys     0m0.000s


备择方案

1)异步

来自 brightinventions.pl - Spring MVC 线程池超时

在 Spring MVC 中,除非使用异步方法,否则无法配置超时。使用异步方法,可以使用 spring.mvc.async.request-timeout= 设置异步请求处理超时之前的时间量(以毫秒为单位)。

我已经设置了 spring.mvc.async.request-timeout=4000 并且在浏览器中出现超时:

 @GetMapping("/test-async")
public Callable<String> getFoobar() {
   return () -> {
      Thread.sleep(12000); //this will cause a timeout
      return "foobar";
   };
}

请参阅 Spring Boot REST API - 请求超时?

2) 小服务过滤器

另一种解决方案是使用 servlet 过滤器 brightinventions.pl - Spring MVC (Kotlin) 中的请求超时

 override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) {
    val completed = AtomicBoolean(false)
    val requestHandlingThread = Thread.currentThread()
    val timeout = timeoutsPool.schedule({
        if (completed.compareAndSet(false, true)) {
            requestHandlingThread.interrupt()
        }
    }, 5, TimeUnit.SECONDS)

    try {
        filterChain.doFilter(request, response)
        timeout.cancel(false)
    } finally {
        completed.set(true)
    }
}

3) Tomcat 卡住线程检测阀?

Tomcat 有一个 Stuck Thread Detection Valve ,但我不知道这是否可以使用 Spring Boot 以编程方式配置。

原文由 Andrei Damian-Fekete 发布,翻译遵循 CC BY-SA 4.0 许可协议

当我调用端点时,请求永远不会超时,它只是无限期地挂起。

server.connection-timeout 不是请求超时。它是空闲连接的超时,即那些已经有请求/响应对并且服务器正在等待第二个请求的连接。它本质上是服务器端读取超时。

原文由 user207421 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题