Unicorn接收截断JSON问题排查请求(附Nginx报错及链路信息)
排查Unicorn接收截断JSON+Nginx readv() Connection Reset问题
结合你给出的链路(请求->ALB->Rails(Unicorn)->API->ALB->Nginx->Tomcat)和报错信息,我来帮你梳理下排查思路和可能的解决方案:
核心问题分析
首先,Nginx的readv() failed (104: Connection reset by peer)错误,本质是Nginx在读取上游Tomcat的响应时,TCP连接被对方(Tomcat或者中间的ALB)主动重置了。而Unicorn收到截断的JSON,是因为这条链路的响应在中途被中断,导致返回给Rails的内容不完整。
可能的原因及排查步骤
1. Tomcat服务自身异常主动断开连接
这是最常见的触发原因,比如:
- 线程池耗尽:查看Tomcat的
server.xml中Connector配置的maxThreads(默认200)和acceptCount(默认100),如果请求量突增,线程池占满后Tomcat会拒绝新连接或重置现有连接。- 检查Tomcat日志(
localhost.log/catalina.out),如果有类似Maximum number of threads (200) created for connector with address的日志,说明线程池容量不足。
- 检查Tomcat日志(
- 请求处理超时:Tomcat默认
connectionTimeout是20000ms(20秒),如果请求处理时间超过这个阈值,Tomcat会主动断开连接。- 可以在
Connector里调整connectionTimeout到合适值(比如60000ms),同时检查业务接口是否有慢查询或阻塞操作。
- 可以在
- 内存不足:如果Tomcat发生
OutOfMemoryError,JVM可能会强制重置连接,查看catalina.out是否有OOM相关日志。
2. 中间ALB的超时配置不匹配
链路中有两层ALB,要确保ALB的超时时间大于下游服务的超时时间:
- 检查连接到Nginx的ALB的空闲超时和请求超时,如果ALB的超时比Nginx的
proxy_read_timeout或Tomcat的connectionTimeout短,ALB会主动断开连接,导致Nginx触发104错误。 - 建议把ALB的超时设置成比下游服务超时多10-20秒,比如如果Tomcat设置60秒超时,ALB设为80秒。
3. Nginx上游连接配置不合理
调整Nginx的代理相关配置,避免提前断开或未处理连接重置:
- 增加
proxy_read_timeout,给Tomcat足够的处理时间:location /some_endpoint { proxy_pass http://xxx.xxx.xx.x:8080; proxy_read_timeout 60s; # 根据业务实际处理时间调整 proxy_connect_timeout 10s; proxy_send_timeout 10s; } - 开启
proxy_next_upstream(仅适用于幂等请求如GET,POST需谨慎),遇到连接重置时重试上游:proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; - 如果使用HTTP/1.1,配置长连接支持,避免频繁建连导致的问题:
proxy_http_version 1.1; proxy_set_header Connection "";
4. 网络层面波动
用tcpdump在Nginx服务器抓包,定位RST包的来源:
tcpdump -i any host xxx.xxx.xx.x and port 8080 -w reset.pcap
回放抓包文件,看RST包是Tomcat发出的,还是ALB发出的,进一步缩小问题范围。
验证方案
- 先调整Nginx的
proxy_read_timeout和对应ALB的超时设置,观察1-2天是否还出现报错。 - 如果Tomcat有线程池或内存问题,先扩容线程池(调整
maxThreads)或优化JVM参数(比如增大堆内存)。 - 对慢接口进行性能优化,减少Tomcat的处理时间,从根源避免超时断开。
内容的提问来源于stack exchange,提问作者reizist
相关产品推荐
相关产品推荐

