Java Spring - server.connection-timeout 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51066238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:56:00  来源:igfitidea点击:

Spring - server.connection-timeout not working

javaspringspring-bootkotlin

提问by Matthew Layton

In my application.propertiesfile I have...

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

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

I know that the file is being loaded correctly because the server is running on port 8086.

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

In the application I have a RestController

在应用程序中,我有一个 RestController

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

When I call the endpoint, the request never times out, it just hangs indefinitely.

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

Am I missing something?

我错过了什么吗?

NOTE:I've also been informed that Tomcat uses this field in minutes, not milliseconds (rather unusual choice IMO). I've tried setting this to server.connection-timeout=1denoting 1 minute, but this didn't work either.

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

NOTE:I don't want anotherHTTP request to cause the previous request to time out, I want each HTTP request to timeout of it's own accord, should too much time elapse to serve the request.

注意:我不希望另一个HTTP 请求导致前一个请求超时,我希望每个 HTTP 请求都自行超时,如果处理请求的时间过长。

采纳答案by Andrei Damian-Fekete

connection-timeoutdoes not apply to long running requests. It does apply to the initial connection, when the server waits for the client to say something.

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

Tomcat docs (not Spring Boot) define it as The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented [...]

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

To test the setting server.connection-timeout=4000I connect using netcatand I don't send any HTTP request/headers. I get:

为了测试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


Alternatives

备择方案

1) Async

1) 异步

From brightinventions.pl - Spring MVC Thread Pool Timeouts:

Brightinventions.pl - Spring MVC 线程池超时

In Spring MVC there is no way to configure a timeout unless you use async method. With async method one can use spring.mvc.async.request-timeout= to set amount of time (in milliseconds) before asynchronous request handling times out.

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

I've set spring.mvc.async.request-timeout=4000and I get a timeout in the browser with this:

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

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

See Spring Boot REST API - request timeout?

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

2) Servlet filter

2) Servlet 过滤器

Another solution would be to use a servlet filter brightinventions.pl - Request timeouts in Spring MVC(Kotlin):

另一种解决方案是使用 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 Stuck Thread Detection Valve?

3)Tomcat卡住线程检测阀?

Tomcat has a Stuck Thread Detection Valvebut I don't know if this can be configured programmatically using Spring Boot.

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

回答by Pankaj Singhal

From the official docs:

来自官方文档

server.connection-timeout= # Time that connectors wait for another HTTP request before closing the connection. When not set, the connector's container-specific default is used. Use a value of -1 to indicate no (that is, an infinite) timeout.

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

Another ref, also mentions the same. It should work for you.

另一个ref也提到了相同的内容。它应该适合你。

回答by user207421

When I call the endpoint, the request never times out, it just hangs indefinitely.

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

server.connection-timeoutisn't a request timeout. It is a timeout for idle connections, i.e. those that have already had a request/response pair and on which the server is now awaiting a second request. It is essentially a server-side read timeout.

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