出现“连接已重置”通常表示通信双方的TCP连接在还未完成应用层交互时被一方通过发送RST或其他方式中断。常见原因包括:服务器进程崩溃、后端超时或配置拦截、网络中间设备(防火墙、负载均衡、IPS)发送RST、MTU或分片问题导致TCP异常,或是TLS握手失败导致连接被重置。
典型场景有:高并发下后端拒绝连接、连接追踪表满导致主动RST、链路丢包或分片导致重传和重置、以及中间链路被运营商或设备限流。
本地排查应分步进行:首先确认DNS解析是否正确,再用ping和traceroute检查连通与路径,再用telnet或curl对指定端口做简单握手测试。示例命令:ping hk-server-ip;traceroute -n hk-server-ip;curl -v --connect-timeout 10 https://域名。
推荐使用:telnet 域名 80 或 openssl s_client -connect 域名:443 来查看TLS握手;若返回RST,说明远端或中间设备主动重置。
别忘了检查本地iptables/Windows防火墙、公司出口策略以及家庭路由器,临时关闭防火墙或换网(手机热点)可快速排除本地问题。
服务器端日志是判断问题来源的关键。首先查看Web服务器日志(例如:/var/log/nginx/error.log、access.log),关注返回码、请求时间与异常条目;其次查看系统日志(/var/log/messages、journalctl -xe)以捕捉内核层错误或OOM;再看应用日志或PHP/nginx upstream错误。
查找关键字:RST、connection reset、timeout、segfault、oom_kill、accept failed 等;使用tail -f /var/log/nginx/error.log、journalctl -u nginx --since "1 hour ago"进行实时观察。
用netstat或ss查看监听与连接状态:ss -tnlp | grep nginx,netstat -s查看TCP统计,观察是否有大量RST或半开连接。
抓包是判断RST来源和序列号关系的最直接方法。可在服务器或网络边界用tcpdump抓取:tcpdump -i eth0 host 客户端IP and tcp and port 443 -w capture.pcap。把抓包文件用Wireshark打开,筛选tcp.flags.reset==1定位哪个IP发送了RST。
观察三次握手(SYN/SYN-ACK/ACK)是否正常,是否在握手后立刻出现RST;检查是否存在重复ACK、重传、MSS/Window缩减或ICMP碎片相关报文;对TLS连接,注意是否在ClientHello/ServerHello阶段出现异常重置。
如果服务器上未见RST来源,可能是上游防火墙或运营商设备介入,需要在边界设备或上游交换机抓包,或使用双端抓包比对时间线。
根据定位结果采取对应措施:若为MTU/分片问题,调整服务器和中间设备MTU或启用TCP MSS调整;若为防火墙/IPS误判,调整规则或在白名单放行;若为连接跟踪表满,增大conntrack表或优化连接保持策略;若为应用超时,调整Nginx的proxy_read_timeout、client_body_timeout、keepalive_timeout等参数。
调整conntrack:sysctl -w net.netfilter.nf_conntrack_max=262144;调整内核TCP参数:sysctl -w net.ipv4.tcp_tw_reuse=1;Nginx示例:proxy_read_timeout 60s; keepalive_timeout 65s。
修复后应通过持续抓包、访问测试与日志监控验证恢复效果,并在监控系统中添加异常RST告警、连接数与错误率监控,确保问题不再复发。