如果20秒内没有任何活动,tomcat会超时?

rog*_*ack 4 java sockets tomcat

如果我设置 tomcat 并从中传输静态文件,我注意到如果客户端从该套接字“暂停”(停止接收)超过 20 秒,那么 tomcat 似乎会任意切断连接(即使请求 URI 标头具有已收到且连接仍处于“已连接”状态 [客户端仍处于活动状态])。什么配置参数控制这个?文档提到但仅与初始标头解析和读取请求正文有关,而不是读取服务器的响应[connectionTimeout?]这里是否发生某种不活动超时?

它是可重现的,从任何 tomcat 应用程序流式传输(大)静态文件,并通过暂停的客户端接收它,例如 test.rb:

require "socket"
host = "localhost"
port = 8080
socket = TCPSocket.new host,port
url = "/your_webapp/large_static_filename.ext"
request = "GET #{url} HTTP/1.0\r\nHost:#{host}\r\n\r\n"
socket.print request
puts "reading"
response = socket.sysread 1_000_000
puts response.length
puts response[0..300]
puts "sleeping 25" # with 10s or several reads separated by 10s, it is OK
sleep 25
response2 = socket.read
# this should equal the total size, but doesn't...
puts "sum=#{response2.length + response.length}"
Run Code Online (Sandbox Code Playgroud)

它与其他服务器一起工作得很好,所以可能没有某种操作系统限制。这只是普通的 Tomcat,所以没有 mod_jk 或工人在起作用......

rog*_*ack 5

影响此“不活动超时”的唯一因素似乎是

<Connector port="8080" ... connectionTimeout=30000 />环境。

并且仅当它尝试主动“发送数据”到线路上时(但不能,因为客户端主动拒绝它或连接已丢失)。如果servlet只是在后台忙于处理cpu,然后写入线路(并且由内核接收或缓冲),没问题,它可以超过connectionTimeout,所以不是this

我的预感是Tomcat似乎有一个“内置”(未记录?无法单独指定?)写入超时设置,默认为connectionTimeout值,ex(来自tomcat源,随机选择):

java/org/apache/tomcat/util/net/NioEndpoint.java
625:            ka.setWriteTimeout(getConnectionTimeout());
Run Code Online (Sandbox Code Playgroud)

现在这是否“不好”还有待解释。在 TCP 通道以某种方式中断(足以停止传输)或客户端在接收字节时“阻塞”之后,会发生 Tomcat 的这种“切断”连接,FWIW ...

FWIW 连接超时设置会影响很多事情

The total amount of time it takes to receive an HTTP GET request.
The total amount of time between receipt of TCP packets on a POST or PUT request.
The total amount of time between ACKs on transmissions of TCP packets in responses.
Run Code Online (Sandbox Code Playgroud)

现在显然还有一个 writeTimeout。

最终结果:我们的网络不稳定,因此这些是“预期”超时/断开的连接(通过具有不同名称的配置,哈哈)。