一尘不染

如果20秒钟内没有活动,tomcat将超时?

tomcat

如果我设置了tomcat并从中流传输了一个静态文件,我注意到如果客户端从该套接字“暂停”(停止接收)大于20s的任何时间,那么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}"

它可以与其他服务器配合使用,因此可能无法发挥某种操作系统的作用。它只是普通的Tomcat,因此没有mod_jk或工人在玩…


阅读 268

收藏
2020-06-16

共1个答案

一尘不染

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

<Connector port="8080" ... connectionTimeout=30000 /> 设置。

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

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

java/org/apache/tomcat/util/net/NioEndpoint.java
625:            ka.setWriteTimeout(getConnectionTimeout());

现在,这是否是“不好的”尚待解释。在TCP通道以某种方式被中断(足以停止传输)或客户端在接收到字节时“阻塞”
FWIW之后,就会发生此错误,这是由tomcat造成的连接“断开” …

FWIW connectionTimeout设置影响很多事情

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.

现在显然也是writeTimeout。

最终结果:我们拥有一个flakey网络,因此这些超时是“预期的”超时。

2020-06-16