告别网络排障恐惧症-告别UI版wireshark:用 curl + tcpdump + tshark + ss 构建完整工具链 - 含TCPIP老鸟常识

告别网络排障恐惧症-告别UI版wireshark:用 curl + tcpdump + tshark + ss 构建完整工具链

你是否曾被 tcpdump 满屏的十六进制吓退?是否在 Wireshark 复杂的 UI 中迷失方向?

本文将用一条清晰的工具链告诉你:90% 的问题用 curl 就能搞定,剩下的 10% 也有优雅的命令行方案。


前言:运维网络排障的完整武器库

做运维的同学都经历过这样的场景:

  1. 用户说"网站打不开"或"系统卡",你登上服务器,一脸茫然。
  2. 想抓包看看,tcpdump 一开,满屏数据飞过,根本不知道该看哪一行。
  3. 把 pcap 文件拉到本地用 Wireshark 打开,在一堆协议字段中点来点去,最后发现只是 DNS 解析慢了一点点......

本文的目标是:给你一套完整的、从应用层到传输层的命令行排障方法论。

先上一张"排障决策树",帮你快速决定用哪个工具:

复制代码
用户报告网络故障
        ↓
┌─────────────────────────────────────────────────────────┐
│  第一步:用 curl -w 测量耗时分布(应用层)                │
│  → 定位问题在哪一层:DNS?TCP?TLS?还是服务器处理?     │
└────────────────────────┬────────────────────────────────┘
                         ↓
              ┌──────────┴──────────┐
              ↓                     ↓
    问题在应用层/HTTP/HTTPS     问题在传输层/非HTTP协议/底层网络
              ↓                     ↓
    ┌─────────────────┐    ┌─────────────────────────────┐
    │ curl -v / -I 等  │    │ 第二步:用 ss 看连接状态    │
    │ 深入诊断         │    │ (套接字层快速巡检)         │
    └─────────────────┘    └──────────────┬──────────────┘
                                          ↓
                               ┌──────────┴──────────┐
                               ↓                     ↓
                          快速定位就够了        需要深入分析报文
                               ↓                     ↓
                    ┌──────────────────┐  ┌──────────────────┐
                    │ tcpdump 轻量抓包  │  │ tshark 深度解析   │
                    │ (快速验证)       │  │ (脚本化分析)     │
                    └──────────────────┘  └──────────────────┘

记住这条铁律:

  • curl → 应用层第一道防线(HTTP/HTTPS/TLS 问题)
  • ss → 套接字层快速巡检(连接状态、端口、进程)
  • tcpdump → 传输层轻量抓包(快速验证、远程 SSH 场景)
  • tshark → 深度协议分析(脚本化提取、统计、无 GUI 环境)

下面,我们逐个拆解这四个工具。

第一部分:curl ------ 应用层排障的瑞士军刀

curl 提供了一个 -w (write-out) 选项,可以输出请求过程中各个阶段的精确耗时。先看一个完整的命令模板:

bash 复制代码
# 创建格式化文件(一次性操作)
cat > curl-format.txt << 'EOF'
    time_namelookup:  %{time_namelookup}\n
       time_connect:  %{time_connect}\n
    time_appconnect:  %{time_appconnect}\n
   time_pretransfer:  %{time_pretransfer}\n
      time_redirect:  %{time_redirect}\n
 time_starttransfer:  %{time_starttransfer}\n
                    ----------\n
         time_total:  %{time_total}\n
EOF

# 使用该格式测试目标 URL
curl -w "@curl-format.txt" -o /dev/null -s "https://www.example.com"

输出示例:

复制代码
    time_namelookup:  0.031
       time_connect:  0.041
    time_appconnect:  0.131
   time_pretransfer:  0.131
      time_redirect:  0.000
 time_starttransfer:  0.188
                    ----------
         time_total:  0.199

各指标含义速查表

变量 含义 包含的阶段 正常范围 异常时指向的问题
time_namelookup DNS 解析时间 域名 → IP < 100ms DNS 服务器慢 / 解析失败
time_connect TCP 三次握手完成时间 SYN, SYN-ACK, ACK < 200ms 网络延迟大 / 防火墙拦截 / 端口不通
time_appconnect SSL/TLS 握手完成时间 加密协商、证书交换 < 300ms 服务端 SSL 性能差 / 证书链过长 / 风控延迟
time_pretransfer 准备传输数据的时间 等于 time_appconnect(无重定向时) --- 存在重定向时会增加
time_starttransfer 收到服务器第一个字节的时间 包含服务器处理时间 --- 应用代码慢 / 数据库查询慢
time_total 总耗时 以上全部 + 数据传输 --- 用户体验总时长

三个黄金锚点,快速定位问题层

复制代码
time_connect      → 网络层问题(防火墙、路由、端口)
time_appconnect   → TLS/SSL 层问题(证书、加密协商、安全策略)
time_starttransfer → 应用层问题(代码逻辑、SQL、第三方 API)

实战案例:云迁移后 HIS 系统间歇性卡顿

故障现象:医院 HIS 系统迁移至阿里云后,高峰时段调用医保接口响应超时(>5秒),但 ping 医保域名延迟正常。

curl 做法

bash 复制代码
curl -w "@curl-format.txt" -o /dev/null -s "https://yibao-api.xxx.cn/pay"

输出:

复制代码
time_namelookup:  0.052
time_connect:     0.078    ← 网络延迟正常
time_appconnect:  4.523    ← 异常!TLS 握手花了 4.5 秒
time_total:       5.189

结论time_connect 正常说明 TCP 连接没问题,但 time_appconnect 高达 4.5 秒,问题锁定在 TLS 握手阶段。结合云迁移后公网 IP 变更的背景,大概率是对端风控策略对新 IP 降级处理。与医保侧沟通后,将新 IP 加入白名单,问题秒解。

curl 更多诊断选项

选项 用途 示例
-v 查看详细交互过程(DNS、TCP、TLS、HTTP 头) curl -v https://example.com
-I 仅获取响应头 curl -I https://example.com
--trace-ascii 保存完整 ASCII 交互流 curl --trace-ascii trace.log https://example.com
--resolve 强制域名解析到指定 IP curl --resolve example.com:443:1.2.3.4 https://example.com
--connect-timeout 设置 TCP 连接超时 curl --connect-timeout 5 https://example.com

第二部分:tcpdump + tshark ------ 底层抓包双雄

当 curl 告诉你"问题在 TCP 层"或者"这不是 HTTP 协议"时,就该请出这两位了。

2.1 tcpdump:轻量、通用、脚本友好

tcpdump 是 Linux/Unix 环境下最经典的命令行抓包工具,几乎预装在所有发行版上,适合远程 SSH 快速排障。

常用命令速查

bash 复制代码
# 基础抓包
sudo tcpdump -i eth0                          # 监听指定网卡
sudo tcpdump -i any -c 100                    # 抓取 100 个包后停止
sudo tcpdump -i eth0 -w capture.pcap          # 保存到文件
tcpdump -r capture.pcap                       # 读取保存的文件

# 按主机和端口过滤
sudo tcpdump -i eth0 host 192.168.1.1         # 指定 IP
sudo tcpdump -i eth0 src 192.168.1.1          # 仅源 IP
sudo tcpdump -i eth0 tcp port 80              # 指定端口
sudo tcpdump -i eth0 'tcp port 80 or tcp port 443'  # 组合条件

# 按协议和标志位过滤
sudo tcpdump -i eth0 icmp                     # ICMP 协议
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'  # 只抓 SYN 包

# 输出格式控制
sudo tcpdump -i eth0 -A -c 5                  # ASCII 格式显示内容
sudo tcpdump -i eth0 -X -c 5                  # 十六进制 + ASCII
sudo tcpdump -i eth0 -tttt                    # 显示精确时间戳
sudo tcpdump -i eth0 -s 0                     # 捕获完整报文(不截断)

# 环形缓冲(生产环境长时间抓包)
sudo tcpdump -i any -s 0 -C 100 -W 5 -w /tmp/cap%03d.pcap
# 说明:每个文件 100MB,保留 5 个,自动循环覆盖

2.2 tshark:终端里的 Wireshark

tshark 是 Wireshark 的命令行版本,它继承了 Wireshark 强大的协议解析能力和显示过滤器语法,特别适合在无 GUI 的服务器上进行深度分析,或集成到自动化脚本中。

tshark 相比 tcpdump 的核心优势

特性 tcpdump tshark
协议解析能力 基础解析 支持数千种协议的深度解析
过滤语法 BPF 捕获过滤器 BPF 捕获过滤器 + Wireshark 显示过滤器
输出格式 固定格式 支持 text/json/fields/ek 等多种格式
统计功能 内置丰富的统计功能(-z 选项)
字段提取 不支持 支持精确提取任意协议字段(-T fields -e

常用命令速查

bash 复制代码
# 基础抓包
tshark -D                           # 列出可用网卡
tshark -i eth0                      # 监听指定网卡
tshark -i eth0 -c 100               # 抓取 100 个包后停止
tshark -i eth0 -a duration:60       # 抓取 60 秒后停止
tshark -i eth0 -w capture.pcapng    # 保存到文件
tshark -r capture.pcapng            # 读取文件

# 捕获过滤器(BPF 语法,与 tcpdump 相同)
tshark -i eth0 -f "tcp port 80"                     # 只抓 80 端口
tshark -i eth0 -f "host 192.168.1.1 and port 443"   # 组合条件

# 显示过滤器(Wireshark 语法,这是 tshark 的杀手锏)
tshark -r capture.pcapng -Y "http.request.method == GET"      # 只看 GET 请求
tshark -r capture.pcapng -Y "tcp.flags.syn == 1 && tcp.flags.ack == 0"  # 只看 SYN 包
tshark -r capture.pcapng -Y "tls.alert_message"               # 只看 TLS 告警

# 提取指定字段(脚本化分析的核心功能)
tshark -r capture.pcapng -T fields -e frame.number -e ip.src -e ip.dst -e tcp.port
# 输出:包序号、源 IP、目的 IP、TCP 端口

tshark -r capture.pcapng -T fields -e frame.number -e tls.alert_message -E separator=,
# 输出 TLS 告警信息,逗号分隔

# 统计功能(-z)
tshark -r capture.pcapng -q -z conv,tcp          # TCP 会话统计
tshark -r capture.pcapng -q -z io,phs            # 协议层次统计

2.3 两大抓包工具的选型指南

场景 推荐工具 理由
远程 SSH 快速验证连通性 tcpdump 轻量、无需额外安装、输出简洁
服务器上需要长时间抓包留痕 tcpdump 或 dumpcap 环形缓冲、资源占用低
需要分析具体协议内容(如 TLS 握手细节) tshark 协议解析深度远超 tcpdump
需要在脚本中批量提取统计信息 tshark -T fields 配合 -e 输出结构化数据
需要在无 GUI 服务器上深度分析 tshark 完整继承 Wireshark 分析能力
非 HTTP 协议故障排查 tshark 支持数千种协议解析

典型工作流

复制代码
tcpdump 采集 → tshark 脚本化提取 → Wireshark 交互分析(如需要)

2.4 实战案例:数据库连接池泄露排查

故障现象 :应用连接 MySQL 偶发 Too many connections,但应用侧连接池配置正常。

排查思路

  1. curl 完全用不上------这是 MySQL 协议,不是 HTTP。

  2. 先用 ss 快速查看当前连接数:

    bash 复制代码
    ss -t state established '( dport = :3306 or sport = :3306 )' | wc -l
    # 发现连接数远超预期,确认存在泄露
  3. tcpdump 在 MySQL 服务器上抓包留证:

    bash 复制代码
    sudo tcpdump -i any port 3306 -s 0 -w mysql.pcap
  4. tshark 批量分析哪些 IP 占用了大量连接:

    bash 复制代码
    tshark -r mysql.pcap -T fields -e ip.src -e ip.dst | sort | uniq -c | sort -rn
    # 发现某台已下线服务器的 IP 仍然持有大量 ESTABLISHED 连接
  5. 根因定位:TCP 半开连接未关闭,MySQL 的 wait_timeout 设置过长。调整参数并清理僵死连接后解决。

此类场景 curl 完全用不上,但 tcpdump + tshark + ss 的组合拳完美覆盖。

第三部分:ss ------ 套接字统计的"快枪手"

ss (Socket Statistics) 是 netstat 的现代替代品。它直接从内核空间获取信息,比 netstat 快得多,尤其在高并发场景下优势明显。

核心优势

  • 速度更快:直接读取内核内存,不走 /proc 文件系统
  • 信息更详细:能显示比 netstat 更丰富的 TCP 状态信息
  • 过滤更强:支持按状态、端口、IP 等维度精确过滤

常用命令速查

bash 复制代码
# 基础查看
ss -tln                 # 查看所有 TCP 监听端口(最常用)
ss -tuln                # 查看所有 TCP/UDP 监听端口
ss -tan                 # 查看所有 TCP 连接(包括监听和非监听)
ss -tulnp               # 显示占用端口的进程信息

# 按状态过滤(ss 的杀手锏功能)
ss -t state established           # 只看已建立的 TCP 连接
ss -t state time-wait             # 只看 TIME_WAIT 状态
ss -t state syn-sent              # 只看正在尝试建立连接的
ss -t '( state not established )' # 查看非 ESTABLISHED 状态的连接

# 按 IP 和端口过滤
ss -t dst 192.168.1.10            # 目的 IP 为 192.168.1.10
ss -t sport eq :22                # 源端口为 22
ss -t dport eq :3306              # 目的端口为 3306
ss -t '( dport = :80 or sport = :80 )'  # 源或目的端口为 80

# 统计信息
ss -s                             # 显示汇总统计(各状态连接数)

输出解读示例

复制代码
$ ss -tan state established
State      Recv-Q Send-Q Local Address:Port      Peer Address:Port
ESTAB      0      0      10.0.1.10:22            192.168.1.5:54321
ESTAB      0      0      10.0.1.10:3306          10.0.2.20:45678
  • Recv-Q / Send-Q:接收和发送队列的积压数据量。非零值可能表示应用处理不过来或网络拥塞。
  • Local Address:Port:本地地址和端口。
  • Peer Address:Port:远端地址和端口。

常见排障场景

问题现象 ss 排查命令 判断依据
服务端口监听不上 `ss -tlnp grep <port>`
连接数过多/泄露 ss -s 或 `ss -tan wc -l`
大量 TIME_WAIT ss -t state time-wait 短连接过多,需调优内核参数或启用连接复用
连接卡在 SYN_SENT ss -t state syn-sent 目标不可达或防火墙丢弃 SYN 包
连接卡在 CLOSE_WAIT ss -t state close-wait 应用未正确调用 close(),代码 bug

第四部分:工具边界与扩展阅读

4.1 curl / tcpdump / tshark / ss 覆盖不到的领域

尽管这四个工具已经覆盖了 95% 的日常排障场景,但以下情况仍需其他工具介入:

场景 为什么上述工具不行 推荐工具
路径网络质量分析(延迟、丢包、路由追踪) curl 只能测端到端,无法看中间每一跳 mtr(My TraceRoute)
MTU 问题(大包无法通过、分片异常) 应用层工具感知不到 MTU ping -M do -s <size> + tcpdump 抓 ICMP
DNS 递归解析链分析 curl 只看最终解析时间 dig +trace
带宽占用分析(哪个进程在疯狂发包) 抓包只能看流量内容,看不出进程级流量 nethogsiftop
进程级网络行为追踪(某进程发起了什么请求) 抓包按端口过滤,但端口会变 strace -e trace=network -p <pid> 或 eBPF
HTTP/HTTPS 代理调试(篡改请求、断点重放) curl 只能发请求,不能拦截修改 Fiddler、Charles
安全入侵检测(实时告警、规则匹配) 抓包工具只管采集,不管告警 Snort
TCP 流重组与内容提取(恢复传输的文件) tcpdump 只抓包,不重组 tcpflow

4.2 扩展阅读:当底层抓包成为刚需时

mtr ------ 网络路径诊断的第一选择

mtr 结合了 pingtraceroute 的功能,可以持续探测到目标主机之间每一跳的丢包率和延迟。这在排查网络质量问题(如间歇性丢包、某跳延迟突然增大)时,比抓包更直接有效。

bash 复制代码
mtr -r -c 100 8.8.8.8   # 发送 100 个包后输出报告
mtr 8.8.8.8             # 实时交互模式

输出解读

  • Loss%:该跳的丢包率。注意,中间跳有丢包但后续跳丢包率低是正常的(控制平面限速),关键是最后一跳的丢包率。
  • Avg / Best / Wrst:延迟的平均值、最小值、最大值。如果某跳延迟突然飙升,说明该节点可能存在拥塞。
dig ------ DNS 解析的显微镜

curl 的 time_namelookup 只能告诉你 DNS 慢了,但 dig +trace 可以完整展示从根域名服务器到权威服务器的整个解析链路,帮你定位是哪个环节出了问题。

bash 复制代码
dig +trace example.com       # 追踪完整解析链路
dig example.com ANY          # 查询所有记录类型
dig -x 8.8.8.8               # 反向解析 IP 到域名
nethogs / iftop ------ 带宽"谁在用"的实时监控

当服务器带宽被打满,你需要快速知道是哪个进程或哪个 IP 在占用流量时:

  • nethogs:按进程显示实时带宽占用。
  • iftop:按源/目的 IP 和端口显示实时流量。
bash 复制代码
sudo nethogs eth0      # 按进程显示
sudo iftop -i eth0     # 按连接显示
strace / eBPF ------ 进程级网络行为的终极武器

当你需要知道某个进程到底发出了什么系统调用、连接到了哪些 IP、读写了多少数据时:

bash 复制代码
# 追踪进程的网络相关系统调用
strace -e trace=network -p <pid>

# 更现代的方式:使用 bpftrace 或 eBPF 工具
tcplife      # 跟踪 TCP 会话的生命周期
tcptop       # 实时显示 TCP 连接的吞吐量

4.3 生产环境抓包的黄金法则

  1. 抓在最接近问题的一端:客户端侧问题就在客户端抓,服务端问题就在服务端抓。
  2. 限定过滤条件 :永远不要无过滤抓包,-fhost/port 限定范围,避免海量无关数据。
  3. 使用 -s 0 捕获完整报文:默认 snaplen 可能截断数据,关键信息丢失。
  4. 启用环形缓冲 :长时间抓包时用 -C -W 或 dumpcap 的 -b filesize,避免磁盘写满。
  5. 多点抓包对比:在客户端、中间设备、服务端分别抓包,对比时序是定位丢包位置的黄金手段。

总结:一张图记住所有

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                        运维网络排障工具链                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   应用层 ──→ curl     (90% 的问题在这里解决)                        │
│             ├── -w:精准测量各阶段耗时                               │
│             ├── -v:查看详细交互                                     │
│             └── --trace:保存完整会话                                 │
│                                                                     │
│   套接字层 ──→ ss      (连接状态巡检,1 秒定位)                      │
│             ├── -tlnp:查看监听端口和进程                            │
│             ├── state:按 TCP 状态过滤                               │
│             └── -s:汇总统计                                        │
│                                                                     │
│   传输层/网络层 ──→ tcpdump + tshark  (深层排障的双刃剑)            │
│                    ├── tcpdump:轻量采集、环形缓冲、脚本友好         │
│                    └── tshark:深度解析、字段提取、统计丰富          │
│                                                                     │
│   扩展武器库 ──→ mtr (路径质量) / dig (DNS) / nethogs (带宽)        │
│                 / strace (进程行为) / tcpflow (流重组)              │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

一句话总结:先用 curl 定位问题层次,再用 ss 快速确认连接状态,最后视需要祭出 tcpdump 采集 + tshark 分析。掌握了这套组合拳,你就能在命令行里优雅地搞定绝大多数网络排障任务,再也不用对着 Wireshark 的 UI 发愁。


附录 B:老手一眼就能看出的 TCP 异常信号

这一节是给有经验的运维准备的"直觉速查表"。老手往往看一眼 ss 输出中的某个状态、某个数字,就能在几秒内判断问题方向。这些判断力来源于对 TCP 状态机、内核参数和网络协议的深刻理解。

一、TCP 连接状态异常速查

老手排查网络问题,第一件事往往不是抓包,而是先看 ss 的状态分布。某些状态的异常堆积,几乎能直接锁定问题类型。

状态 正常场景 一眼异常的阈值 对应的问题
SYN_RECV 服务器收到 SYN,等待 ACK 完成握手,通常极少量且瞬间消失 持续堆积数百条以上 SYN Flood DDoS 攻击;或半连接队列(默认仅 128)太小导致正常连接也被丢弃
SYN_SENT 客户端发出 SYN,等待服务端 SYN+ACK,通常瞬时状态 大量堆积且持续 目标端口不通/防火墙丢弃 SYN 包/目标服务挂掉
ESTABLISHED 正常业务连接 数量远超业务预期且无应用层数据 连接泄漏(应用未关闭连接);CC 攻击(建立连接后不发数据,耗尽连接池)
TIME_WAIT 主动关闭方等待 2MSL(约 60 秒) 数千至上万条 短连接过多(HTTP/1.0 频繁建连断连);需启用 tcp_tw_reuse 或改长连接
CLOSE_WAIT 被动关闭方收到 FIN,等待应用调用 close() 持续堆积且不消失 应用代码 Bug :应用未正确调用 close() 关闭 socket
FIN_WAIT1 / FIN_WAIT2 主动关闭方等待对方 FIN 或 ACK 大量停留在这些状态 对端不响应 FIN;网络丢包;防火墙丢弃 FIN 包

老手常用命令:

bash 复制代码
# 快速看状态分布
ss -s

# 按状态精确统计
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn

# 专门看 SYN_RECV(半连接堆积)
ss -tan state syn-recv | wc -l

# 专门看 CLOSE_WAIT(代码 bug 信号)
ss -tan state close-wait

二、SYN_RECV 大量堆积 = DDoS(老手直觉的第一反应)

老手看到 ss -tan 里有大量 SYN_RECV,第一反应就是:SYN Flood 攻击

原理: TCP 三次握手中,服务器收到 SYN 后会分配资源(半连接队列、内存缓冲区)并返回 SYN+ACK,然后进入 SYN_RECV 状态等待客户端的 ACK。攻击者利用这种"资源消耗不对称",发送大量伪造源 IP 的 SYN 请求,故意不完成三次握手,耗尽服务器的半连接队列,导致正常请求被丢弃。

老手直觉判断标准:

  • Linux 默认半连接队列容量仅 128net.ipv4.tcp_max_syn_backlog
  • 如果 SYN_RECV 数量持续 > 100 且居高不下 → 极可能是攻击
  • 某金融科技公司案例:业务低峰期突增 3 万条 TCP 连接,其中 78% 处于半开状态,最终确认为 SYN Flood

快速验证:

bash 复制代码
# 看半连接数
ss -tan state syn-recv | wc -l

# 看队列是否溢出(关键证据)
netstat -s | grep -i "SYNs to LISTEN"
# 如果有 "SYNs to LISTEN sockets dropped",说明半连接队列已满,正常请求被丢弃

防御措施:

  • 启用 SYN Cookie:sysctl -w net.ipv4.tcp_syncookies=1(队列满时用加密 Cookie 代替队列存储)
  • 调大半连接队列:sysctl -w net.ipv4.tcp_max_syn_backlog=10240

三、CLOSE_WAIT 堆积 = 代码 Bug(老手最常见的发现)

CLOSE_WAIT 是 TCP 状态机中的一个"死穴"------它永远在等应用调用 close()

老手判断逻辑:

  • CLOSE_WAIT 是被动关闭方(收到对方 FIN)的状态
  • 如果 CLOSE_WAIT 持续堆积且不消失 → 应用代码没有调用 close() 关闭连接
  • 这是应用层 bug,不是网络问题,调内核参数没用,必须改代码

快速定位:

bash 复制代码
# 看 CLOSE_WAIT 数量
ss -tan state close-wait | wc -l

# 看是哪个进程的 CLOSE_WAIT
ss -tanp state close-wait | grep -i close

四、Recv-Q / Send-Q 队列积压

ss 输出中的 Recv-Q 和 Send-Q 是老手必看的两个数字,一眼就能判断数据流向的瓶颈在哪一端。

队列 含义 正常值 异常时的问题
Recv-Q 接收缓冲区中待应用读取的数据量 0 或极小 非零且持续增长:应用处理速度跟不上网络接收速度,应用层有性能瓶颈
Send-Q 发送缓冲区中待发送的数据量 0 或极小 非零且持续增长 :网络拥塞、对端接收窗口满(rwnd=0)、或对端应用不读数据

老手特别注意: ss -lnt 监听状态的 Recv-Q 含义不同!

对于 LISTEN 状态 的套接字(ss -lnt):

  • Recv-Q :当前已完成三次握手、等待应用 accept() 的连接数
  • Send-Q :该监听套接字的最大全连接队列长度(min(backlog, somaxconn)

如果 ss -lnt 中某端口的 Recv-Q 接近或等于 Send-Q ,说明全连接队列已满,新连接会被丢弃。这通常是因为应用 accept() 太慢或 backlog 配置太小。

快速诊断命令:

bash 复制代码
# 检查监听队列是否堆积
ss -lnt | awk 'NR>1 {if ($2>0) print $0}'

# 看内核是否记录队列溢出
netstat -s | grep -i "listen queue"
# "times the listen queue of a socket overflowed" → 全连接队列溢出过

五、常见指标阈值速查

老手对数字非常敏感,以下阈值是经验积累下来的"红线":

指标 正常/健康范围 警告阈值 严重阈值 含义与排查方向
TCP 重传率 < 0.1% > 1% > 5% 网络丢包严重/拥塞;检查交换机端口错误计数、网卡丢包、带宽打满
RTT 延迟(内网) < 1ms > 5ms > 10ms 网络拥塞/路由绕路/交换机排队;用 mtr 看各跳延迟
RTT 延迟(同城公网) < 5ms > 20ms > 50ms 公网质量波动/路由切换;联系运营商或用 CDN
TIME_WAIT 数量 < 5000 > 10000 > 30000 短连接过多;考虑启用连接复用或改长连接
本地端口范围 默认约 28K 可用 > 60% 占用 > 80% 占用 TIME_WAIT 耗尽端口;sysctl net.ipv4.ip_local_port_range 扩大范围

重传率的快速估算:

bash 复制代码
# 从内核统计粗略计算(两次采样间隔)
netstat -s | grep "segments retransmited"

TIME_WAIT 的参考值:

  • 单个 IP 的可用端口范围约 28,000~65,000 个(取决于 ip_local_port_range
  • 如果 TIME_WAIT 数量接近可用端口数的 50%,就应考虑优化
  • 可通过扩大端口范围、启用 tcp_tw_reuse、或改用长连接解决

六、案例:一个老手的 30 秒直觉判断

以下是一个典型的真实排障流程,展示老手如何凭直觉快速锁定问题:

背景: 凌晨 3 点接到告警:"用户反馈网站打不开,503 错误"。

老手的 30 秒操作:

bash 复制代码
# 第 1 秒:看连接状态分布
$ ss -s
Total: 15842
TCP:   15840 (estab 12000, closed 3400, synrecv 520, timewait 3200)

# 第 2 秒:一眼看到 synrecv=520(正常应 < 10)
$ ss -tan state syn-recv | head -5
State    Recv-Q Send-Q Local Address:Port  Peer Address:Port
SYN-RECV 0      0      10.0.1.10:80        45.xxx.xxx.xxx:12345
SYN-RECV 0      0      10.0.1.10:80        212.xxx.xxx.xxx:54321
...

# 第 10 秒:确认队列溢出
$ netstat -s | grep -i "SYNs to LISTEN"
    2347 SYNs to LISTEN sockets dropped

# 第 20 秒:看源 IP 分布,全是随机 IP,无规律
$ ss -tan state syn-recv | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | head
    1 103.45.xxx.xxx
    1 185.23.xxx.xxx
    1 45.132.xxx.xxx
...

结论: SYN Flood 攻击。synrecv=520 远超正常阈值,源 IP 随机分散,且有大量 SYNs dropped 记录。立即启用 SYN Cookie + 调大半连接队列,同时联系云厂商清洗流量。

七、总结:老手的"一眼直觉"口诀

看到的 第一反应 下一步
SYN_RECV 堆积 SYN Flood DDoS 启用 SYN Cookie,看源 IP 分布
CLOSE_WAIT 堆积 代码没调 close() 找开发改代码
TIME_WAIT > 1 万 短连接太多 调内核参数或改长连接
Recv-Q(监听)接近 Send-Q accept() 太慢 / backlog 太小 调大 backlog 或优化应用
Recv-Q(已连接)非零 应用读数据太慢 优化应用处理逻辑
Send-Q(已连接)非零 网络拥塞 / 对端不读 查网络质量、对端应用
SYN_SENT 堆积 目标不可达 telnet 测端口,查防火墙
重传率 > 5% 网络丢包严重 检查网卡/交换机错误计数

掌握这些直觉判断,你就拥有了老手排查网络问题的"肌肉记忆"。配合本文正文中的 curl / tcpdump / tshark / ss 完整工具链,绝大多数运维网络故障都能在几分钟内定位根因。

相关推荐
你觉得脆皮鸡好吃吗1 小时前
SQL注入 手工注入
网络·数据库·sql·安全·web安全·网络安全学习
盟接之桥2 小时前
盟接之桥®制造业EDI软件:专注制造,为制造业服务,让全球供应链协同更有底气
网络·安全·低代码·汽车·制造
eam0511232 小时前
简单园区网
网络
Cat_Rocky2 小时前
网络技术基础一点点
运维·服务器·网络
Lyyaoo.2 小时前
【JAVA网络面经】应用层协议
java·开发语言·网络
@insist1232 小时前
网络工程师-非网络核心知识操作系统与系统开发基础
网络·网络工程师·软考·软件水平考试
郝开2 小时前
Docker Compose 本地环境搭建:独立 Compose + 共享网络 + .env 统一管理(架构设计篇)
网络·docker·容器
爱喝雪碧的可乐2 小时前
【Redis 毁灭计划】7 大高危操作打崩线上服务!从缓存雪崩到数据库宕机,90% 程序员都踩过的坑
开发语言·网络·redis·php