netstat统计的tcp连接数与⁄proc⁄pid⁄fd下socket类型fd数量不一致的分析

新blog地址:

http://hengyunabc.github.io/netstat-difference-proc-fd-socket-stat/


最近,线上一个应用,发现socket数缓慢增长,并且不回收,超过警告线之后,被运维监控自动重启了。

首先到zabbix上观察JVM历史记录,发现JVM-Perm space最近两周没有数据,猜测是程序从JDK7切换到JDK8了。问过开发人员之后,程序已经很久没有重启了,最近才重新发布的。而在这期间,线上的Java运行环境已经从JDK7升级到JDK8了。

因为jdk8里没有Perm space了,换成了Metaspace。

###netstat
到线上服务器上,用netstat来统计进程的connection数量。

netstat -antp | grep pid | wc -l

发现比zabbix上的统计socket数量要少100多,netstat统计只有100多,而zabbix上监控数据有300多。

于是到/proc/$pid/fd下统计socket类型的fd数量:

cd /proc/$pid/fd
ls -al | grep socket | wc -l

发现数据和zabbix上的数据一致。

###netstat是怎么统计的
####下载netstat的源代码
http://unix.stackexchange.com/questions/21503/source-code-of-netstat

apt-get source net-tools

从netstat的代码里,大概可以看到是读取/proc/net/tcp里面的数据来获取统计信息的。
####java和c版的简单netstat的实现
java版的

http://www.cs.earlham.edu/~jeremiah/LinuxSocket.java

C版的:

http://www.netmite.com/android/mydroid/system/core/toolbox/netstat.c

####用starce跟踪netstat

strace netstat -antp 

可以发现netstat把/proc 下的很多数据都读取出来了。于是大致可以知道netstat是把/proc/pid/fd 下面的数据和/proc/net/下面的数据汇总,对照得到统计结果的。

####哪些socket会没有被netstat统计到?
又在网上找了下,发现这里有说到socket如果创建了,没有bind或者connect,就不会被netstat统计到。

http://serverfault.com/questions/153983/sockets-found-by-lsof-but-not-by-netstat

实际上,也就是如果socket创建了,没有被使用,那么就只会在/proc/pid/fd下面有,而不会在/proc/net/下面有相关数据。

简单测试了下,的确是这样:

int socket = socket(PF_INET,SOCK_STREAM,0); //不使用

另外,即使socket是使用过的,如果执行shutdown后,刚开始里,用netstat可以统计到socket的状态是FIN_WAIT1。过一段时间,netstat统计不到socket的信息的,但是在/proc/pid/fd下,还是可以找到。

中间的时候,自己写了个程序,把/proc/pid/fd 下的inode和/proc/net/下面的数据比较,发现的确有些socket的inode不会出现在/proc/net/下。
####用lsof查看
用lsof查看socket inode:

###触发GC,回收socket
于是尝试触发GC,看下socket会不会被回收:

jmap -histo:live <pid>

结果,发现socket都被回收了。

再看下AbstractPlainSocketImpl的finalize方法:

    /**
     * Cleans up if the user forgets to close it.
     */
    protected void finalize() throws IOException {
        close();
    }

可以看到socket是会在GC时,被close掉的。
写个程序来测试下:

public class TestServer {
	public static void main(String[] args) throws IOException, InterruptedException {
		for(int i = 0; i < 10; ++i){
			ServerSocket socket = new ServerSocket(i + 10000);
			System.err.println(socket);
		}
		System.in.read();
	}
}

先执行,查看/proc/pid/fd,可以发现有相关的socket fd,再触发GC,可以发现socket被回收掉了。
##其它的东东
####anon_inode:[eventpoll]

ls -al /proc/pid/fd

可以看到有像这样的输出:

661 -> anon_inode:[eventpoll]

这种类型的inode,是epoll创建的。

再扯远一点,linux下java里的selector实现是epoll结合一个pipe来实现事件通知功能的。所以在NIO程序里,会有anon_inode:[eventpoll]和pipe类型的fd。
####为什么tail -f /proc/$pid/fd/1 不能读取到stdout的数据
http://unix.stackexchange.com/questions/152773/why-cant-i-tail-f-proc-pid-fd-1
##总结
原因是jdk升级之后,GC的工作方式有变化,FullGC执行的时间变长了,导致有些空闲的socket没有被回收。

本文比较乱,记录下一些工具和技巧。

公众号

欢迎关注公众号:横云断岭的专栏,专注分享Java,Spring Boot,Arthas,Dubbo。

横云断岭的专栏

<think>好的,我需要回答用户的问题:“ss是什么的缩写”。首先,我要确定用户的问题是关于Linux系统中的命令行工具ss,而是其他可能同样缩写为SS的内容。因为根据之前的对话历史,用户之前询问了netstatss的区别,所以这里的ss应该指的是Linux的网络工具。 接下来,我需要确认ss的全称是什么。根据我的知识库,ss是Socket Statistics的缩写,用于查看系统的套接字统计信息。但为了确保准确性,我需要进一步验证这个信息。查阅相关资料,比如官方文档或可信的技术资源,确认ss的全称确实是Socket Statistics。此外,还可以查看ss命令的手册页(man ss),里面通常会提到全称。 用户可能想知道ss的缩写背后的含义,以及为什么这个工具被命名为ss。需要解释它的用途功能,以便用户理解缩写的来源。同时,可能需要将ss其他类似工具(如netstat)进行简要对比,强调其优势,比如更高效、基于netlink等。 此外,用户可能对ss的功能常见用法感兴趣,所以可以在解释缩写的同时,简要介绍ss的主要功能常用命令示例。例如,使用ss查看TCP连接、监听端口、过滤特定条件等。这仅回答了问题,还提供了额外的实用信息,帮助用户更好地使用这个工具。 需要注意的是,回答要简明扼要,避免过于技术化,同时确保信息准确。需要检查是否有其他可能的缩写冲突,比如在某些上下文中SS可能代表其他术语,但在Linux网络工具中,ss确实代表Socket Statistics。因此,在回答中应明确指出这一点,避免混淆。 最后,总结ss作为Socket Statistics的缩写,强调其在现代Linux系统中的重要性优势,如高性能、详细统计信息等,以巩固用户的理解,并可能推荐用户优先使用ss替代旧的工具如netstat。</think>### `ss` 的缩写含义核心功能 `ss` 是 **Socket Statistics**(套接字统计)的缩写,它是 Linux 系统中用于**实时监控分析网络连接状态**的命令行工具,属于 `iproute2` 工具集的一部分。以下是其关键细节: --- #### 一、**名称解析** - **缩写来源** `ss` 取自 **S**ocket **S**tatistics(套接字统计),直接表明其核心功能是**统计管理网络套接字**。 - **定位** 替代传统工具 `netstat`,专注于更高效、更详细地展示网络连接信息。 --- #### 二、**核心功能** 1. **连接状态查看** 显示 TCP、UDP、UNIX Domain Socket 等协议的连接状态(如 `LISTEN`, `ESTABLISHED`, `TIME-WAIT`)。 **示例**: ```bash ss -tna # 查看所有 TCP 连接(简洁模式) ``` 2. **内核级细节展示** 支持输出 TCP 内部参数(如拥塞窗口、RTT 时间、重传次数): ```bash ss -ti # 显示详细 TCP 信息 ``` 3. **高级过滤** 使用 **BPF 过滤器语法**(类似 `tcpdump`)精准筛选连接: ```bash ss -nt '( dport = :80 or sport = :80 )' # 过滤端口 80 的 TCP 连接 ``` 4. **统计汇总** 快速统计各协议连接数、状态分布: ```bash ss -s # 输出全局连接统计 ``` --- #### 三、**技术优势** - **性能高效** 直接通过 `netlink` 接口内核通信,避免解析 `/proc` 文件的性能瓶颈,**万级连接秒级响应**。 - **协议支持全面** 支持 TCP、UDP、SCTP、UNIX Domain Socket 等协议,覆盖现代网络场景。 - **信息密度高** 输出字段紧凑,支持扩展参数(如进程绑定、套接字选项)。 --- #### 四、** `netstat` 的对比** | **特性** | `ss` | `netstat` | |----------------|-----------------------------------|------------------------------------| | **数据来源** | 内核 `netlink` 接口(直接高效) | 解析 `/proc/net` 文件(速度较慢) | | **维护状态** | 活跃开发(`iproute2` 工具集) | 已停止维护(`net-tools` 工具集) | | **典型用途** | 高并发连接分析、深度调试 | 简单连接检查(旧系统兼容) | --- #### 五、**常用场景示例** 1. **快速查看监听端口** ```bash ss -lntp # 显示所有 TCP 监听端口及关联进程 ``` **输出示例**: ``` LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3)) ``` 2. **分析 TIME-WAIT 状态连接** ```bash ss -nt state time-wait # 过滤所有 TCP TIME-WAIT 连接 ``` --- ### 总结 - **缩写本质**:`ss` = **Socket Statistics**,直指其统计分析套接字的核心功能。 - **推荐使用场景**:需高效处理海量连接、获取内核级网络参数或使用高级过滤时,优先选择 `ss`。 - **迁移意义**:作为 `netstat` 的现代替代品,`ss` 在性能、功能维护性上全面占优。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值