工业边缘网关上常见三类网络问题:服务没有按预期监听、连接堆积在异常状态、外联链路不清楚。ss 是 Linux iproute2 工具集里的 socket 统计工具,通过内核 netlink 接口读取 TCP、UDP、Unix socket 等连接信息,适合在资源有限的边缘设备上做快速定位。
本文按实际排障顺序整理 ss 的常用参数、过滤方法、TCP 状态、连接队列、输出细节和运维边界。文中示例以 Linux 和 iproute2 为主,不同发行版的输出列可能略有差异。
一、为什么用 ss
netstat 来自 net-tools,很多老运维习惯仍在使用;ss 与 ip 同属 iproute2,是现代 Linux 更推荐的查看方式。
| 对比项 | netstat | ss |
|---|---|---|
| 数据来源 | 依赖 /proc/net 等路径 | 通过 netlink 从内核获取 |
| 大量连接时的速度 | 相对慢 | 通常更快 |
| 过滤能力 | 依赖文本处理较多 | 支持 state、port、address 等内核侧过滤 |
| TCP 详情 | 输出较有限 | 可查看 timer、TCP info、uid、inode 等 |
| 维护状态 | net-tools 已长期停止积极开发 | 随 iproute2 维护 |
需要保留 netstat 也没有问题,但新脚本、镜像和巡检工具建议优先使用 ss,减少对旧包的依赖。
二、安装与基础命令
多数主流发行版默认已安装 iproute2。如果没有:
# Debian / Ubuntu
sudo apt update && sudo apt install iproute2
# RHEL / CentOS / Fedora
sudo dnf install iproute2
常用基础命令:
# 查看 TCP / UDP 监听端口,不做名称解析
ss -tuln
# 查看所有 TCP 连接
ss -tan
# 查看 TCP 连接与对应进程;查看其他用户进程需要 root
sudo ss -tnp
# 查看 socket 汇总统计
ss -s
# 查看 socket 内存使用
ss -m
参数含义:
| 参数 | 含义 |
|---|---|
-t | TCP socket |
-u | UDP socket |
-l | 监听中的 socket |
-a | 所有状态 |
-n | 不解析服务名和主机名 |
-p | 显示进程信息,常配合 sudo |
-s | 输出汇总统计 |
-m | 显示 socket 内存信息 |
生产排障建议加 -n。DNS 反查不仅慢,还可能因为解析器异常导致命令卡住。
三、常用过滤方法
1. 按 TCP 状态过滤
ss -tn state established
ss -tn state listening
ss -tn state time-wait
ss -tn state syn-sent
ss -tn state close-wait
2. 按端口过滤
推荐使用表达式写法,语义更清晰:
# 查看监听在 8080 端口的 TCP socket
sudo ss -tlnp '( sport = :8080 )'
# 查看目的端口为 443 的连接
ss -tn '( dport = :443 )'
# 查看源端口为 8080 的连接
ss -tn '( sport = :8080 )'
3. 按地址和网段过滤
# 目的地址在指定网段
ss -tn dst 192.168.1.0/24
# 源地址在指定网段
ss -tn src 192.168.10.0/24
# 组合状态和端口
ss -tn '( state established and dport = :443 )'
过滤表达式可以先在终端小范围验证,再放进巡检脚本。不要把 ss -tan 的完整输出直接交给高延迟日志系统,连接数高的边缘网关可能一次输出几十万行。
四、读懂 TCP 状态
| 状态 | 含义 | 排障方向 |
|---|---|---|
LISTEN | 服务端等待连接 | 检查监听地址、端口和 backlog |
SYN-SENT | 客户端已发出 SYN,未收到 SYN+ACK | 检查路由、防火墙、服务端可达性 |
SYN-RECV | 服务端收到 SYN,等待第三次握手 ACK | 大量出现需关注半连接和异常来源 |
ESTABLISHED | 连接已建立 | 看数量、分布、来源和增长趋势 |
FIN-WAIT-1 | 主动关闭方已发送 FIN | 看对端是否能正常响应 |
FIN-WAIT-2 | 主动关闭方等待对端 FIN | 关注对端应用是否迟迟不关闭 |
TIME-WAIT | 主动关闭方等待旧报文消逝 | 通常正常,需结合增速和业务形态判断 |
CLOSE-WAIT | 被动关闭方收到 FIN,应用尚未关闭 socket | 重点检查应用漏关闭、连接池泄漏 |
CLOSING | 双方同时关闭 | 少量可观察,异常增多需抓包分析 |
LAST-ACK | 被动关闭方等待最后 ACK | 观察对端 ACK 是否送达 |
CLOSED | socket 已关闭 | 通常表示无活动连接 |
不要把所有非 ESTABLISHED 状态都当成故障。TIME_WAIT 是 TCP 正常机制,CLOSE_WAIT 持续增长才更像是应用代码没有释放连接。
五、查看连接详细信息
# 显示 TCP timer,例如 keepalive、retransmit
ss -tno
# 显示 TCP 内部信息,例如 rtt、cwnd、retrans
ss -tni
# 显示 uid、inode、skmem 等扩展信息
ss -tne
# 显示 socket 内存
ss -tnm
# 显示进程、PID 和 fd;建议 sudo
sudo ss -tnp
-i 的输出适合分析单条异常连接,例如重传、RTT 抖动和拥塞窗口变化。如果要长期采集,建议先在边缘侧聚合指标,而不是持续保存完整原始输出。
六、服务端口排障
1. 确认服务是否监听
sudo ss -tlpn '( sport = :8080 )'
重点看四列:
| 输出项 | 判断点 |
|---|---|
Netid | 是 TCP、UDP 还是 Unix socket |
State | TCP 服务应为 LISTEN |
Local Address:Port | 监听地址是否正确 |
Process | 是否为预期进程 |
常见问题:
- 应用监听
127.0.0.1:8080,外部访问失败; - IPv4 / IPv6 监听行为与预期不一致;
- 容器内监听正常,但没有映射到宿主机;
- 端口被旧进程占用;
systemd 服务已退出; - 安全组、iptables、nftables 或防火墙阻断访问。
2. 确认进程占用
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser -n tcp 8080
lsof 和 fuser 不是所有精简镜像都预装,ss -p 通常更适合作为第一步。定位到 PID 后,再结合 systemctl status、journalctl、容器运行时和 /proc/$PID 查看来源。
3. 看监听队列
ss -ltn
对 LISTEN socket,Recv-Q 表示当前 accept 队列中的连接数,Send-Q 表示配置的最大 backlog。如果应用接受连接的速度长期低于新建速度,会出现队列增长、连接超时或握手完成后被丢弃。
处理方向:
- 检查应用线程池、事件循环阻塞和下游调用超时;
- 合理调整应用 listen backlog;
- 在反向代理层限制并发;
- 结合
nstat或/proc/net/netstat观察丢队、溢出和重传; - 不要只升级机器规格,先确认瓶颈在接收、处理还是下游。
七、连接堆积与状态分析
1. 统计各状态数量
ss -Htan | awk '{print $1}' | sort | uniq -c | sort -nr
建议记录正常时期的基线。例如同样的产线时段、同样的采集频率、同样的设备在线数下,ESTABLISHED 和 CLOSE_WAIT 的合理范围是多少。没有基线时,单次数字很难判断异常。
2. CLOSE_WAIT 堆积
sudo ss -tnp state close-wait
CLOSE_WAIT 表示对端已经关闭,本端应用还没有调用关闭。常见原因:
- HTTP 客户端没有复用或释放响应;
- 数据库连接池未处理断连;
- 设备 TCP 连接异常断开后,网关业务线程阻塞;
- 异步任务异常退出但 socket 未释放;
- 子进程继承 fd 后未关闭。
处理重点在应用生命周期管理:明确谁创建连接、谁负责关闭、异常路径是否释放、超时后是否强制回收。
3. TIME_WAIT 数量高
ss -Htan state time-wait | wc -l
TIME_WAIT 多不一定是故障。大量短连接、主动关闭方频繁重建连接,都会产生 TIME_WAIT。
优先检查:
- 是否没有使用 HTTP keep-alive 或连接池;
- 是否每条消息都新建 MQTT / HTTP / 数据库连接;
- 采集任务是否高频串行连接同一服务;
- 是否存在异常重连风暴;
- 上游是否主动要求频繁断开。
tcp_tw_reuse 只应谨慎用于明确的出站短连接场景,不能当作万能参数。临时修改命令如下:
sudo sysctl net.ipv4.tcp_tw_reuse
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
若要持久化,应写入 /etc/sysctl.d/ 并在测试后执行 sysctl --system。更重要的是先优化连接复用和重连策略,避免用内核参数掩盖应用设计问题。
4. SYN-SENT 挂起
ss -tnp state syn-sent
常见原因:
- 目标 IP 或端口错误;
- 路由不可达;
- 防火墙丢弃回包;
- NAT 或安全组限制;
- 服务端负载过高;
- DNS 解析到了错误地址。
下一步可以结合 ip route get、ping、traceroute、防火墙规则和应用超时日志判断。不要只看连接状态,还要确认源地址是否是预期的出口地址。
八、外联与安全排查
1. 查看指定进程的外联
sudo ss -tnp | grep 'pid=12345'
也可以先确认进程是否存在:
ps -p 12345 -o pid,comm,args
2. 查看访问指定目标的连接
ss -tnp '( dport = :443 )'
ss -tnp dst 203.0.113.0/24
3. 输出无表头结果,便于脚本处理
ss -Htn state established
工业边缘设备外联应尽量收敛:明确目标地址、端口、协议、证书和重试策略。未知外联增加时,除了网络排查,还要检查包来源、进程、启动项、镜像版本和密钥使用情况。
九、与 netstat 的对照
| 目的 | netstat 写法 | ss 写法 |
|---|---|---|
| 查看监听端口 | netstat -tuln | ss -tuln |
| 查看所有连接和进程 | sudo netstat -anp | sudo ss -tanp |
| 查看协议统计 | netstat -s | ss -s |
| 查看 TCP 监听 | netstat -tln | ss -tln |
| 查看路由表 | netstat -r | ip route |
| 查看接口信息 | netstat -i | ip -s link |
迁移脚本时不要只做字符串替换。ss 的输出列、状态大小写和过滤语法与 netstat 不同,应结合实际输出调整 awk、grep 和监控规则。
十、工程实践
1. 固定命令与输出字段
巡检脚本应固定 -n、-H、状态过滤和字段顺序,避免 DNS 解析、名称服务变化或表头影响解析。
2. 先过滤,再统计
让内核或 ss 先按状态、端口、地址过滤,再交给 wc、awk 或日志采集器,减少边缘设备额外开销。
3. 建立连接基线
至少记录:
- 每个服务的
LISTEN数量和地址; ESTABLISHED分布;CLOSE_WAIT正常上限;SYN-SENT持续时间;- 监听队列峰值;
- 外联目标清单;
- 断网与恢复期间的连接回收时间。
4. 把连接状态接入观测
只看瞬时 ss 输出,很难判断趋势。可以周期采集:
- 各状态连接数;
- 指定服务端口连接数;
- 指定进程外联数;
- 监听队列长度;
- 重连次数和重连失败次数;
- socket 内存占用。
指标应带上站点、网关、服务名、端口和进程标签,但不要直接暴露敏感内网拓扑到公开面板。
5. 注意容器和命名空间
容器内看到的网络命名空间与宿主机不同。排查时先明确对象:
CONTAINER_PID=$(docker inspect --format '{{.State.Pid}}' mycontainer)
sudo nsenter -t "$CONTAINER_PID" -n ss -tnp
如果进程运行在 Kubernetes Pod 中,应进入对应网络命名空间查看,或在节点上按 Pod 网络与容器进程继续追踪。
十一、常见坑与处理
| 坑 | 现象 | 处理 |
|---|---|---|
不加 -n | 命令卡住,输出慢 | 排障时禁用名称解析 |
普通用户执行 -p | 看不到其他用户进程 | 使用 sudo 或授权后采集 |
| 过滤表达式写错 | 结果为空或报语法错误 | 用引号包裹表达式,先小范围验证 |
| 只看一次输出 | 误判瞬时抖动 | 周期采集并与基线对比 |
| 见到 TIME_WAIT 就调参 | 问题被掩盖,行为更难预测 | 先优化连接复用和重连风暴 |
| 忽略 CLOSE_WAIT | 连接逐渐泄漏 | 排查应用关闭逻辑和连接池 |
| 忽略监听地址 | 服务只监听回环地址 | 明确 127.0.0.1 与 0.0.0.0 的边界 |
| 容器内外视角混淆 | 宿主机和容器看到的连接不同 | 进入正确 network namespace |
| 输出直接进日志 | 磁盘被大量连接数据写满 | 先过滤、聚合和限速 |
TL;DR
ss -tuln 看监听,ss -tan 看状态,sudo ss -tnp 看进程,ss -s 看汇总。过滤时优先使用 state、sport、dport、src、dst 表达式,并用 -n 避免名称解析。CLOSE_WAIT 持续增长通常指向应用未释放连接;TIME_WAIT 高不一定异常,应先优化短连接和重连策略。监听队列、外联目标和网络命名空间也是工业边缘排障的关键边界。
在 Zenova EdgeOS 这类工业边缘运行环境中,ss 可用于排查设备接入、本地 API、北向上传和代理链路的 socket 状态,并将连接堆积、监听异常和外联变化纳入网关运维观测。

440

被折叠的 条评论
为什么被折叠?



