【问题标题】:Spring - server.connection-timeout not workingSpring - server.connection-timeout 不起作用
【发布时间】:2018-12-06 13:17:02
【问题描述】:

在我的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 请求都自行超时,也应该处理请求需要很长时间。

【问题讨论】:

  • 您使用的是什么服务器?雄猫?
  • @NikolayRusev - 是的,Tomcat。
  • 您使用的是哪个 spring-boot 版本?
  • @MukhtiarAhmed 1.5.3-发布
  • 您可以通过以下链接找到解决方案stackoverflow.com/questions/31461444/…

标签: java spring spring-boot kotlin


【解决方案1】:

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 Thread Pool Timeouts

在 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 - request timeout?

2) Servlet 过滤器

另一种解决方案是使用 servlet 过滤器 brightinventions.pl - Request timeouts in 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 以编程方式配置。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 那么什么是请求超时?
    • @MatthewLayton 请求超时是您在客户端设置的计时器,用于超时接收响应的第一部分。
    【解决方案3】:

    来自官方docs

    server.connection-timeout= # 连接器在关闭连接之前等待另一个 HTTP 请求的时间。如果未设置,则使用连接器特定于容器的默认值。使用值 -1 表示没有(即无限)超时。

    另一个ref,也提到了同样的事情。它应该适合你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 1970-01-01
      • 2015-01-15
      • 1970-01-01
      相关资源
      最近更新 更多