Total 小于 kernel 且差值持续增大说明存在 socket 泄漏或回收异常;Total 是用户态可见的活跃 socket 数,kernel 包含未清理的 CLOSE_WAIT、TIME_WAIT、SYN_RECV 及 orphaned 等内核维护的 socket 结构体。

ss -s 输出里 Total 和 kernel 数值差很大说明什么
这通常意味着 socket 泄漏或回收异常,不是“连接多”的简单问题。Total 是用户态可见的活跃 socket 数(比如已建立、监听中),kernel 是内核实际维护的 socket 结构体总数——包括还没清理的 CLOSE_WAIT、未释放的 TIME_WAIT、半连接 SYN_RECV,甚至 orphaned(进程已死但连接还在)。
如果 kernel 持续比 Total 高 10% 以上,尤其差值随时间增大,就得查:应用是否漏调 close()、文件描述符是否未释放、net.ipv4.tcp_tw_reuse 是否关闭导致 TIME_WAIT 积压。
-
ss -s第一行只是总览,真正要看的是下面 TCP 行里的estab、timewait、orphaned、synrecv这几列 -
orphaned > 0是硬指标:进程没了,socket 还卡在内核里,基本等于泄漏 -
synrecv长期非零,可能net.core.somaxconn太小,accept 队列溢出,不是业务量大,是服务端吞吐瓶颈
用 ss 查看特定状态的 TCP 连接(比如只看 ESTABLISHED)
别用 ss -t | grep ESTABLISHED,那会漏掉状态字段被截断的情况(比如某些内核版本状态列在第2或第3位)。正确做法是用 ss 自带的状态过滤语法:
-
ss -tan state established:只输出 ESTABLISHED 的 IPv4 TCP 连接,-n避免 DNS 解析拖慢速度 -
ss -tan state time-wait:查 TIME_WAIT,注意写法是time-wait,不是timewait或TIME_WAIT -
ss -tan state listening:等价于ss -tln,但更明确,适合脚本里判断端口是否真在监听
状态名必须小写、带连字符,常见可选值有:established、syn-sent、syn-recv、fin-wait-1、time-wait、close、listening、closed。
为什么 ss -tuln 比 netstat -tuln 更可靠
因为 ss 直接读取内核 socket 子系统(通过 tcp_diag 模块),而 netstat 是解析 /proc/net/tcp 等文本文件,中间多一层格式转换和权限检查。在容器或低权限环境里,netstat -p 经常报 can't identify protocol 或直接没进程信息,ss -tulp 却能正常显示。
-
ss -tulp要求 root 或CAP_NET_ADMIN权限才能看到进程名;没权限时,ss -tuln仍可查端口和地址,只是-p无效 -
netstat在 CentOS 8+/Ubuntu 18.04+ 默认不装,需额外apt install net-tools或yum install net-tools,ss几乎所有发行版都预装 -
ss -tuln执行耗时通常在 1–3ms,netstat -tuln在连接数过万时可能到 200ms+,监控脚本里务必用ss
想统计某端口的连接数?别用 grep,用 ss 原生过滤
写 ss -tan | grep ':8080' | wc -l 看似简单,但容易误匹配(比如 IP 里含 8080、端口范围跨段)。ss 支持按本地/远端地址和端口精确过滤:
-
ss -tn sport = :8080:本地源端口是 8080 的连接(比如本机发起的 outbound 请求) -
ss -tn dport = :8080:目标端口是 8080 的连接(最常用,查谁连了你的 8080 服务) -
ss -tn dst 192.168.1.100:8080:目标 IP+端口精确匹配 - 组合用:
ss -tn state established dport = :8080,又快又准
注意:端口号前必须加冒号 :,否则会被当成字符串匹配;sport/dport 只对 TCP/UDP 有效,UNIX socket 不支持。
ss -s 和 ss -tan state established 这两个命令配合看,比任何单条命令都管用。很多人忽略 ss -s 里 orphaned 和 synrecv 这两列,结果花半天查业务代码,其实问题早就在内核统计里标红了。


















