Linux TCP 连接问题排查指南

一、问题现象

TCP 连接问题通常表现为:

  • 客户端连接超时或连接被拒绝
  • 连接建立后数据传输缓慢或中断
  • 大量连接处于 TIME_WAITCLOSE_WAIT 状态
  • 服务端无法接受新连接

二、排查工具

2.1 查看 TCP 连接状态

1
2
3
4
5
6
7
8
# 查看所有 TCP 连接
ss -tanp

# 统计各状态连接数
ss -tan | awk '{print $1}' | sort | uniq -c

# 查看特定端口的连接
ss -tan | grep :80

2.2 常用连接状态说明

状态 含义 可能原因
ESTABLISHED 连接已建立 正常状态
SYN_SENT 已发送 SYN,等待响应 网络不通或对方未响应
SYN_RECV 收到 SYN,已回复 SYN-ACK 等待客户端 ACK
TIME_WAIT 主动关闭方等待 2MSL 正常关闭流程
CLOSE_WAIT 被动关闭方等待应用关闭 应用未调用 close()
FIN_WAIT1/2 等待关闭确认 正常关闭流程

三、常见问题排查

3.1 连接超时 (SYN_SENT 状态过多)

可能原因:

  • 目标服务未启动
  • 防火墙拦截
  • 网络路由问题

排查步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 检查目标服务是否监听
ss -tlnp | grep <端口>

# 2. 检查本地防火墙
iptables -L -n | grep <端口>
firewall-cmd --list-all

# 3. 测试网络连通性
telnet <目标 IP> <端口>
nc -zv <目标 IP> <端口>

# 4. 追踪路由
traceroute <目标 IP>

3.2 CLOSE_WAIT 状态过多

原因: 对端已关闭连接,但本地应用未调用 close() 释放连接。

排查:

1
2
3
4
5
# 查看 CLOSE_WAIT 连接及对应进程
ss -tanp | grep CLOSE_WAIT

# 检查应用日志,查找连接未释放的 bug
journalctl -u <服务名> -f

解决: 重启服务或修复应用代码中的连接泄漏问题。

3.3 TIME_WAIT 状态过多

原因: 高并发短连接场景下,主动关闭方会进入 TIME_WAIT 状态。

优化方案:

1
2
3
4
5
6
7
# 编辑 /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200

# 生效配置
sysctl -p

⚠️ 注意:tcp_tw_reuse=1 仅适用于客户端,服务端慎用。

3.4 连接被拒绝 (Connection Refused)

排查:

1
2
3
4
5
6
7
8
# 1. 确认服务是否运行
systemctl status <服务名>

# 2. 确认监听地址
ss -tlnp | grep <端口>

# 3. 检查监听地址是否为 0.0.0.0(允许外部访问)
# 如果只监听 127.0.0.1,外部无法连接

四、内核参数调优

4.1 调整连接队列

1
2
3
4
5
6
#  backlog 队列长度
net.ipv4.tcp_max_syn_backlog = 2048
net.core.somaxconn = 2048

# 生效
sysctl -p

4.2 调整端口范围

1
2
# 本地端口范围(高并发客户端)
net.ipv4.ip_local_port_range = 1024 65535

五、抓包分析

当常规排查无法定位问题时,使用 tcpdump 抓包:

1
2
3
4
5
# 抓取特定端口数据包
tcpdump -i any -n port <端口> -w tcp.pcap

# 实时查看 TCP 握手过程
tcpdump -i any -n -tttt port <端口> and tcp[tcpflags] & (tcp-syn|tcp-ack) != 0

使用 Wireshark 分析 .pcap 文件,重点关注:

  • 三次握手是否完整
  • 是否有重传 (Retransmission)
  • 是否有乱序 (Out-of-Order)
  • 窗口大小 (Window Size) 是否合理

六、排查流程图

1
2
3
4
5
连接问题
├── 连接超时 → 检查服务状态 → 检查防火墙 → 检查路由
├── 连接拒绝 → 检查服务监听 → 检查监听地址
├── CLOSE_WAIT 多 → 检查应用代码 → 重启服务
└── TIME_WAIT 多 → 调整内核参数 → 优化连接复用

七、总结

TCP 连接问题排查核心思路:

  1. 先看状态:用 ss 确定连接处于什么状态
  2. 再查服务:确认目标服务是否正常运行
  3. 检查网络:防火墙、路由、DNS
  4. 分析应用:连接泄漏、资源不足
  5. 最后抓包:深入分析网络层问题

参考文档:

  • man ss
  • man sysctl.conf
  • TCP/IP 详解 卷 1