记录线上数据上传提示网络连接异常的故障

发布于:2025-09-12 ⋅ 阅读:(15) ⋅ 点赞:(0)

在这里插入图片描述
这条错误日志的核心含义是:Nginx作为反向代理,在从上游服务器(即你的Tomcat服务,地址为127.0.0.1:8090)读取响应头时,上游服务器突然关闭了连接(未正常完成TCP挥手),导致Nginx接收数据失败

日志各部分含义拆解:

  • 2025/09/09 09:53:46:错误发生的时间。
  • [error] 29155#0: *3648728:Nginx的错误标识(进程ID 29155,请求ID 3648728)。
  • recv() failed (104: Connection reset by peer):核心错误——Nginx调用recv()函数接收数据时失败,错误码104表示“连接被对端重置”(即上游Tomcat主动关闭了连接)。
  • while reading response header from upstream:错误发生的场景——Nginx正在从上游服务器读取响应头(还没读完响应头,连接就断了)。
  • client: 39.144.231.220:发起请求的客户端IP。
  • server: upload.mbfwyun.com:Nginx上配置的虚拟主机(对应你的上传服务域名)。
  • request: "POST /mbxcbp/servlet/BpzyxcJsAhServlet.do HTTP/1.1":客户端发起的具体请求(POST方法,访问的Servlet路径)。
  • upstream: "http://127.0.0.1:8090/...":请求被转发到的上游服务器(你的Tomcat服务,8090端口)。
  • host: "upload.mbfwyun.com:8080":客户端请求的Host头信息。

关键结论:

Connection reset by peer” 是典型的“上游服务异常关闭连接”错误,意味着:
Tomcat在处理 POST /mbxcbp/servlet/BpzyxcJsAhServlet.do 这个请求时,还没给Nginx返回完整的响应头,就强行关闭了与Nginx的连接(可能是Tomcat内部出错、超时、资源耗尽等原因)。

结合你的场景(Tomcat处理大文件上传和数据推送),最可能的原因仍是:

  1. Tomcat处理该请求时发生未捕获的异常(如OOM、代码错误),导致进程/线程崩溃,连接被强制关闭;
  2. 该请求处理时间过长,超过了Tomcat或Nginx的超时配置,导致先关闭连接;
  3. Tomcat的线程池/内存资源耗尽,无法继续处理请求,主动重置新连接。

建议优先查看Tomcat在 2025/09/09 09:53:46 左右的日志(如 catalina.out),定位是否有具体的错误堆栈,这是排查的关键。

要让Tomcat避免主动关闭连接(尤其是针对大文件上传、长时间数据推送等场景),需要从 连接超时配置长连接保持请求处理超时 三个维度调整Tomcat的核心参数,主要在 server.xmlConnector 节点中配置。以下是具体参数及配置方法:

关键配置参数及说明(修改 server.xmlConnector 节点)

<Connector 
    port="8090" 
    maxHttpHeaderSize="8192" 
    protocol="org.apache.coyote.http11.Http11NioProtocol"  <!-- 已配置的NIO协议 -->
    URIEncoding="UTF-8" 
    maxThreads="500" 
    minSpareThreads="100" 
    maxSpareThreads="400"
    enableLookups="false" 
    redirectPort="8443" 
    acceptCount="500"
    
    <!-- 1. 连接超时:避免Tomcat因客户端长时间未发送数据而关闭连接 -->
    connectionTimeout="300000"  <!-- 等待客户端发送请求的超时时间(5分钟,默认20秒),延长以适应缓慢的客户端 -->
    
    <!-- 2. 上传超时:专门针对文件上传的超时控制(核心参数) -->
    connectionUploadTimeout="86400000"  <!-- 上传过程的超时时间(24小时,原配置10小时,可根据业务延长) -->
    disableUploadTimeout="false"  <!-- 启用上传超时控制(与connectionUploadTimeout配合生效) -->
    
    <!-- 3. 长连接保持:避免Tomcat主动关闭空闲的长连接 -->
    keepAliveTimeout="600000"  <!-- 长连接(Keep-Alive)的空闲超时时间(10分钟,默认5秒),延长以保持连接 -->
    maxKeepAliveRequests="-1"  <!-- 一个长连接上允许处理的最大请求数(-1表示无限制,默认100),避免达到次数后关闭连接 -->
    
    <!-- 4. 其他已配置的关键参数 -->
    maxPostSize="0"  <!-- 关闭POST数据大小限制(大文件上传必需) -->
    useBodyEncodingForURI="true" 
    relaxedPathChars="&lt;&gt;,[\]^`{|}~" 
    relaxedQueryChars="&lt;&gt;,[\]^`{|}~"
    maxSwallowSize="-1"  <!-- 避免大文件上传被截断(已添加) -->
/>

核心参数详解(为何能避免Tomcat主动关闭连接)

  1. connectionTimeout="300000"

    • 作用:控制Tomcat等待客户端发送请求头的超时时间(从连接建立到客户端发送完请求头的时间)。
    • 优化:默认20秒(20000ms),对于网络缓慢的客户端(如大文件上传前的请求准备)可能不够,延长至5分钟(300000ms)可避免Tomcat因“客户端发送请求太慢”而主动关闭连接。
  2. connectionUploadTimeout="86400000"

    • 作用:专门针对文件上传过程的超时控制(从请求头接收完成到上传结束的时间)。
    • 优化:原配置10小时(36000000ms),若有超大文件(如几十GB),可延长至24小时(86400000ms),确保上传过程中Tomcat不会因“上传耗时太长”而主动断开连接。
  3. keepAliveTimeout="600000"maxKeepAliveRequests="-1"

    • 作用:控制HTTP长连接(Keep-Alive)的行为:
      • keepAliveTimeout:长连接在“处理完一个请求后”的空闲等待时间(默认5秒),延长至10分钟(600000ms),避免Tomcat快速关闭空闲连接。
      • maxKeepAliveRequests:一个长连接上允许处理的最大请求数(默认100),设为-1表示无限制,避免“达到请求次数后Tomcat主动关闭连接”。
  4. maxSwallowSize="-1"(已配置)

    • 作用:当客户端意外断开连接时,Tomcat会“吞咽”(处理)剩余的请求体数据,默认限制2MB,超过则强制关闭连接。设为-1关闭限制,避免大文件上传时因客户端中断导致Tomcat主动关闭连接。

额外注意事项

  1. 配合Nginx超时配置
    确保Nginx的 proxy_read_timeout(等待Tomcat响应的超时)大于Tomcat的 connectionUploadTimeout,避免Nginx先于Tomcat关闭连接(例如Nginx设置 proxy_read_timeout 86400s;)。

  2. 应用层超时
    若后端Java代码中有单独的超时控制(如ServletasyncTimeout、框架级超时),需同步延长,避免应用代码主动中断请求。

  3. 资源监控
    延长超时可能导致Tomcat连接/线程占用更久,需监控服务器内存、线程数(通过jstack或Tomcat Manager),确保maxThreads等参数足够支撑并发。

通过以上配置,可最大限度减少Tomcat主动关闭连接的情况,尤其适配大文件上传和长时间数据推送场景。

当连接被强制断开(如服务器发送RST包强制关闭TCP连接,而非正常的FIN挥手)时,客户端侧的响应会因客户端类型(浏览器、APP、自定义客户端等)和断开时机(请求发送中、响应接收中、连接空闲时)而有所不同,但核心表现是“网络连接异常中断”,具体如下:

1. 浏览器作为客户端(最常见场景)

  • 错误提示
    浏览器会直接显示“网络连接异常”类提示,具体文字因浏览器而异:
    • Chrome/Firefox:通常显示 ERR_CONNECTION_RESET(连接已重置),或“无法访问此网站,连接被重置”。
    • Safari:可能显示“网络连接意外终止”或“无法加载页面,因为网络连接中断”。
  • 表现细节
    • 若在请求发送阶段断开(客户端刚发请求就被断):浏览器可能快速提示错误,无响应内容。
    • 若在响应接收阶段断开(已收到部分响应):可能显示不完整的页面(如半截HTML),或仅加载部分资源(如图片/样式缺失),随后提示网络错误。

2. 自定义客户端(如APP、API调用工具)

  • 错误捕获
    客户端程序(如Java、Python、JS等开发的应用)会捕获到底层网络异常,具体异常类型因语言/框架而异:
    • Java:抛出 java.net.SocketException: Connection reset(连接被重置)。
    • Python:抛出 ConnectionResetError: [Errno 104] Connection reset by peer
    • JavaScript(浏览器端):fetchXMLHttpRequest 会触发 error 事件,response 不可用,status 为0(非HTTP状态码)。
  • 业务表现
    应用程序通常会将异常转化为用户可理解的提示,例如:
    • “网络连接中断,请重试”
    • “上传失败,服务器连接丢失”
    • “请求超时或网络异常”

3. 文件上传场景(你的核心场景)

若连接在大文件上传过程中被强制断开,客户端侧的响应更具体:

  • 进度提示:上传进度条可能突然卡住、停止更新,或回退到0%。
  • 错误提示:明确提示“上传中断”“网络连接被强制关闭”“与服务器的连接丢失,无法继续上传”等。
  • 数据状态:客户端通常无法知道服务器是否已接收部分文件(因连接中断无响应),因此可能需要用户重新上传(除非应用实现了断点续传逻辑)。

核心共性:无有效HTTP响应

无论哪种客户端,连接被强制断开时,客户端都无法收到完整的HTTP响应(包括HTTP状态码、响应头/体)。因为TCP连接在HTTP协议处理完成前被终止,客户端只能感知到“底层网络异常”,而无法解析到服务器的正常HTTP反馈(如200/500等状态码)。

这与“服务器正常返回500错误”完全不同——后者是完整的HTTP响应,而前者是纯网络层的强制中断。


网站公告

今日签到

点亮在社区的每一天
去签到