3、传输层故障排查:端口未开放、防火墙规则拦截、TCP三次握手失败、连接超时与重置

传输层,说白了就是两台机器之间的「对话通道」。CMS 系统里,应用服务器和数据库、缓存、消息队列之间的通信,全得靠它。通道不通,啥业务都跑不起来。我排查过太多这类问题了,今天把最常见的几种情况掰开揉碎了讲。

核心思路:传输层故障,本质上就是「端口不通」或「连接不稳」。先定位是哪个环节断了,再对症下药。

3.1 端口未开放:服务没在听

你想想看,客户端去连一个端口,结果服务端根本没人在那等着。这就是端口未开放。最常见的原因:服务没启动,或者启动后监听错了地址。

怎么查?

  • 服务端用 ss -tlnpnetstat -tlnp 看监听列表。我习惯用 ss,更快。
  • LISTEN 状态的端口。如果目标端口没出现,那就是服务没起来。
  • 注意监听地址:0.0.0.0:3306 表示所有网卡都监听,127.0.0.1:3306 只监听本地。CMS 的数据库如果只监听本地,远程应用肯定连不上。

避坑指南:我曾经遇到过,MySQL 配置了 bind-address = 127.0.0.1,结果应用服务器死活连不上。查了半天才发现是监听地址的问题。改成 0.0.0.0 就好了。

3.2 防火墙规则拦截:端口被「关在门外」

端口开放了,但防火墙把连接请求给拦了。这就像你家门开着,但门口有个保安不让你进。

排查步骤:

  1. 先确认防火墙是否开启:systemctl status firewalldiptables -L -n
  2. 查看规则:firewall-cmd --list-alliptables -L -n --line-numbers
  3. 临时放行测试:firewall-cmd --add-port=3306/tcp。如果通了,就是规则问题。

注意:云服务商的安全组规则也要检查。我见过太多人只查了服务器本地防火墙,忘了云平台还有一层。两层都放行才行。

3.3 TCP 三次握手失败:连接建立不了

TCP 三次握手是建立连接的基础。客户端发 SYN,服务端回 SYN+ACK,客户端再回 ACK。任何一步出问题,连接就建不起来。

典型场景:

  • SYN 包发不出去:路由不通,或者客户端 IP 被服务端拒绝。
  • SYN+ACK 回不来:服务端有响应,但客户端收不到。可能是 NAT 问题,或者服务端配置了 tcp_tw_recycle 导致时间戳错乱。
  • ACK 丢失:网络丢包严重,或者半连接队列满了。

怎么抓?tcpdump -i any host 10.0.0.1 and port 3306 抓包。看三次握手的标志位。如果只有 SYN 发出,没有 SYN+ACK 回来,那就是服务端没响应。如果 SYN+ACK 回来了,但客户端没回 ACK,那就是客户端的问题。

实战经验:我记得有一次,CMS 的数据库连接池频繁报错。抓包发现,服务端发了 SYN+ACK,但客户端一直没回 ACK。查了半天,是客户端的 net.ipv4.tcp_tw_reusetcp_tw_recycle 配置冲突,导致时间戳校验失败。关掉 tcp_tw_recycle 就好了。

3.4 连接超时与重置:连接建好了,但被断了

连接超时,就是客户端等太久没响应。连接重置(RST),就是连接被强制中断。这两种情况在 CMS 系统里很常见。

连接超时原因:

  • 服务端负载高,处理不过来。
  • 网络延迟大,丢包严重。
  • 客户端设置的超时时间太短。比如 PHP 的 default_socket_timeout 只有 60 秒,但数据库查询要 90 秒。

连接重置原因:

  • 服务端主动发 RST:比如端口没监听,或者应用层主动关闭连接。
  • 防火墙或中间设备发 RST:比如安全策略检测到异常流量。
  • 半连接超时:服务端没收到客户端的 ACK,超时后发 RST。

避坑指南:我曾经排查过一个 CMS 的图片上传问题。上传大文件时,连接总是被重置。抓包发现,是 Nginx 的 proxy_read_timeout 设置得太短,导致反向代理主动发了 RST。调大超时时间就解决了。

3.5 知识体系图:传输层故障排查全景

下面这张图,是我自己总结的排查路径。从现象出发,一步步定位根因。

传输层故障排查全景图 连接失败 端口是否开放? 端口未开放 端口已开放 检查服务是否启动 检查监听地址是否正确 防火墙是否拦截? 抓包分析三次握手 最终定位:端口 / 防火墙 / 握手 / 超时重置

3.6 常用命令速查表

场景 命令 说明
查看端口监听 ss -tlnp 显示所有 TCP 监听端口及进程
查看防火墙规则 firewall-cmd --list-all 列出当前防火墙放行规则
抓包分析握手 tcpdump -i any host 10.0.0.1 and port 3306 抓取指定主机的 TCP 包
测试端口连通性 telnet 10.0.0.1 3306 快速测试端口是否可达
查看连接状态 ss -tan 显示所有 TCP 连接状态

重要提醒:生产环境抓包要谨慎。数据量大的时候,tcpdump 会消耗大量 CPU 和磁盘 I/O。我建议先加过滤条件,只抓目标端口的数据。比如 tcpdump -i any port 3306 -c 1000,抓 1000 个包就停。

传输层的问题,说白了就是「连不连得上」和「连上了稳不稳」。端口、防火墙、握手、超时重置,这四个点挨个排查,大部分问题都能定位。嗯,今天就先聊到这。下一章我们讲应用层故障,那又是另一番天地了。


公众号:蓝海资料掘金营,微信deep3321