生产问题-下载大文件:客户端连接关闭

34 阅读3分钟

报错

客户端连接被关闭(出现 connection reset by peer)——导致这个报错,应该就是keepalive_timeout和send_timeout。

而且时间间隔每次都是60s,即耗时超过60s就报错——这个是通过日志看到的,请求接口开始时间到报错时间刚好60s


org.apache.catalina.connector.ClientAbortException: iava,io,I0Exception: connection reset by peer at org.apache.catalina.connector.0utputBuffer.realWriteBytes(0utputBuffer.java:371) ~[catalina.jar:8.5.66]at org.apache.catalina.connector.0utputBuffer.appendByteArray(0utputBuffer.java:815) ~lcatalina.jar:8.5.66]at org.apache.catalina.connector.0utputBuffer.append(0utputBuffer.java:744) ~[catalina.jar:8.5.66]英·曰首出。at org.apache.catalina.connector.0utputBuffer.writeBytes(0utputBuffer.java:406) ~[catalina.jar:8.5.66at org.apache.catalina.connector.0utputBuffer.write(0utputBuffer,iava:384) wfcatalina, iar:8.5.66 at org, apache.catalina,connector,Coyote0utputstream,writelcoyote0utputstream, iava:96) ~fcatalina,iar:8.5.66lat iava. io.BufferedOutputStream.flushBuffer(BufferedOutputStream.iava:82) ~?:1.8.0 251]at java. io.BufferedOutputstream.write(BufferedOutputstream.java:126) ~?:1.8.0 251]at com. xxx.moudles .softCenter.servlet.HttpPointDownloadDiagsoftServlet.downloadDiagsoft(HttpPointDownloadDiagsoftserv

主要是send_timeout

下载超时时间,或者叫返回数据给客户端的超时时间

默认值60s

如果没有配置,默认值60s

超时时间不是整个时间,而是断开时间

比如默认值是60s,如果下载大文件完整耗时是五分钟,但是只要中间断开时间没有超过60s,就没有影响

如果断开时间超过60s,客户端连接就会被关闭

断开时间就是没有写数据的时间,比如因为网络的原因等等

send_timeout和proxy_send_timeout区别

两个配置不一样,一个是上传(proxy_send_timeout),一个是下载(send_timeout )

简单可以这么理解

实际是,一个是nginx写服务器的超时时间,一个是nginx返回客户端的超时时间

最佳实践

文本数据

默认60s就ok

下载小文件

120s

下载大文件

300s

客户端关闭连接

用户点击

按理来说,客户端关闭连接,是客户端主动关闭连接,而不是服务器的配置问题

但是日志显示每次间隔一分钟报错,不可能用户每次都间隔一分钟主动断开连接——所以应该是服务器配置问题

api接口

如果是基于api接口调用,有可能是客户端设置了超时时间是60s

为什么服务器配置会导致报错客户端关闭连接

原因在于nginx

问题答案
是否是客户端关闭连接?是的,从 Tomcat 视角看是客户端断开(其实是 Nginx 中途断开)
为什么每次都差不多是 60s?因为 Nginx 默认 send_timeout 60s,刚好触发断开
是否 Nginx 导致了这个错误?✔️ 是的,Nginx send_timeout 会断连接,Tomcat 会因此抛出 reset by peer 错
如何避免?设置 send_timeout 300s 或更高;让 Nginx 等待更久再判断连接超时

更新

之前是同时反馈固定一分钟报错,但是其实不是。

刚才查了一下日志, 超时时间不是一分钟,而是随机的,所以应该是用户主动关闭连接。如果是固定时间间隔报错,可能是服务器配置或者客户端配置导致的。

而且运维反馈,这个报错之前就有,一直存在。