☰
PHP程序员从零到一用 tcpdump 抓包分析 TCP 重传的庖丁解牛
2026/10/5 3:47:22 网站建设 项目流程

从零到一用tcpdump分析 TCP 重传,不是“执行命令看输出”,而是“通过网络层证据链,定位 PHP 应用层性能问题”。
TCP 重传是网络拥塞、丢包、服务端慢响应的明确信号,常导致API 偶发高延迟、502、队列假活。


一、TCP 重传原理:为何发生?

1.重传触发条件
类型触发条件特征
超时重传(RTO)发送方未收到 ACK > RTO间隔指数退避(1s, 2s, 4s…)
快速重传(Fast Retransmit)收到 3 个重复 ACK立即重传,无退避
2.PHP 场景根因
  • 服务端慢:
    • FPM 进程满 → 无法及时recv()→ 客户端重传;
  • 网络丢包:
    • 跨机房/公网传输丢包;
  • 客户端 Bug:
    • 防火墙丢弃 ACK 包。

🔑核心:重传 = 网络层对“未收到确认”的补偿机制。


二、抓包命令:精准捕获重传包

1.基础命令(过滤重传)
# 抓取本机 9000 端口(FPM)的重传包sudotcpdump -i any -nn -ttt\'tcp and port 9000 and (tcp[tcpflags] & (tcp-rst|tcp-syn) == 0)'\-w fpm_retrans.pcap
  • 关键过滤:
    • tcp[tcpflags] & (tcp-rst|tcp-syn) == 0→排除 SYN/RST(仅抓数据包);
    • -w→ 保存为 pcap 文件(供 Wireshark 分析)。
2.实时分析重传
# 实时显示重传包(Linux)sudotcpdump -i any -nn -e\'tcp and port 9000'|grep-E'retransmission|duplicate'
  • 输出示例:
    10:00:01.123456 IP 127.0.0.1.50000 > 127.0.0.1.9000: Flags [.], seq 12345, ack 67890, win 65535, length 100 10:00:02.123456 IP 127.0.0.1.50000 > 127.0.0.1.9000: Flags [.], seq 12345, ack 6789 <== retransmission
3.高级过滤(仅重传)
# 使用 tcpdump 的重传过滤(需较新版本)sudotcpdump -i any -nn -Q'tcp.analysis.retransmission'

⚠️注意:

  • -i any:抓所有接口(含 lo);
  • 生产环境慎用:高流量下可能丢包。

三、分析方法:从 pcap 到根因

1.Wireshark 分析(推荐)
  • 步骤:
    1. 用tcpdump -w fpm_retrans.pcap抓包;
    2. 用 Wireshark 打开 pcap;
    3. 过滤重传:tcp.analysis.retransmission;
    4. 查看统计:Statistics → TCP Stream Graphs → Time-Sequence。
  • 关键指标:
    • 重传间隔:
      • 1s, 2s, 4s →超时重传(RTO);
      • 连续快速重传 →快速重传。
    • 重传方向:
      • 客户端 → 服务端 →服务端未 ACK(FPM 慢);
      • 服务端 → 客户端 →客户端未 ACK(网络丢包)。
2.命令行分析(无 GUI)
# 统计重传包数量tshark -r fpm_retrans.pcap -Y'tcp.analysis.retransmission'|wc-l# 查看重传时间间隔tshark -r fpm_retrans.pcap -Y'tcp.analysis.retransmission'-T fields -e frame.time_delta
3.关联 PHP 日志
  • 步骤:
    1. 抓包同时记录 PHP 慢日志:
      ; php-fpm.conf slowlog = /var/log/php-slow.log request_slowlog_timeout = 1s
    2. 对比时间戳:
      • 重传时间 ≈ PHP 慢日志时间 →FPM 慢导致重传。

四、PHP 场景联动:实战诊断

场景 1:API 偶发 2 秒延迟
  • 步骤:
    1. 抓包:
      sudotcpdump -i lo -nn -w api_retrans.pcap port9000
    2. 模拟请求:
      whiletrue;docurlhttp://localhost/api;sleep0.1;done
    3. 分析 pcap:
      • 发现超时重传(间隔 1s, 2s);
      • 重传方向:客户端 → FPM;
    4. 查 PHP 慢日志:
      • 对应时间有sleep(3)记录;
    5. 根因:
      • 代码含sleep()→ FPM 未及时 ACK → 客户端重传。
场景 2:跨机房 API 高延迟
  • 步骤:
    1. 在服务端抓包:
      sudotcpdump -i eth0 -w cross_dc.pcaphostclient_ip
    2. 分析:
      • 快速重传(3 个重复 ACK);
      • 重传方向:服务端 → 客户端;
    3. 根因:
      • 跨机房网络丢包 → 客户端未收到数据 → 重传。
场景 3:队列消费者假活
  • 步骤:
    1. 抓 Redis 连接:
      sudotcpdump -i lo -w redis_retrans.pcap port6379
    2. 分析:
      • 重传间隔 200ms →TCP Keepalive 重传;
    3. 根因:
      • 消费者卡死 → 未 ACK Redis 数据 → 连接假活。

五、高危陷阱

🚫 陷阱 1:“重传 = 网络问题”
  • 真相:
    • 70% 重传源于服务端慢(FPM/DB);
    • 先查 PHP 慢日志,再查网络。
🚫 陷阱 2:“抓包必须用 Wireshark”
  • 真相:
    • tshark命令行足够(生产环境无 GUI);
    • 关键指标:重传方向 + 间隔。
🚫 陷阱 3:“重传包少可忽略”
  • 真相:
    • 1% 重传率 → 10% 延迟增加(TCP 拥塞控制);
    • 必须根治。

六、终极心法:tcpdump 是网络的“X 光”

不要只看“有重传”,
要看“重传背后的系统状态”
。

  • 重传 + FPM 慢日志→ 优化 PHP 代码;
  • 重传 + 高丢包率→ 优化网络;
  • 重传 + 无日志→ 检查客户端/防火墙。

当你能用 tcpdump + PHP 慢日志构建证据链,
网络问题就从黑盒,
变为可量化的性能杠杆
。

这,才是专业 PHP 工程师的网络观。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询