netstat统计的tcp连接数与⁄proc⁄pid⁄fd下socket类型fd数量不一致的分析
最近,线上一个应用,发现socket数缓慢增长,并且不回收,超过警告线之后,被运维监控自动重启了。
首先到zabbix上观察JVM历史记录,发现JVM-Perm space最近两周没有数据,猜测是程序从JDK7切换到JDK8了。问过开发人员之后,程序已经很久没有重启了,最近才重新发布的。而在这期间,线上的Java运行环境已经从JDK7升级到JDK8了。
因为jdk8里没有Perm space了,换成了Metaspace。
###netstat
到线上服务器上,用netstat来统计进程的connection数量。
|
1
|
netstat -antp | grep pid | wc -l
|
发现比zabbix上的统计socket数量要少100多,netstat统计只有100多,而zabbix上监控数据有300多。
于是到/proc/$pid/fd下统计socket类型的fd数量:
|
1
2
|
cd /proc/$pid/fd
ls -al | grep socket | wc -l
|
发现数据和zabbix上的数据一致。
###netstat是怎么统计的
####下载netstat的源代码
http://unix.stackexchange.com/questions/21503/source-code-of-netstat
|
1
|
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
|
1
|
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/下面有相关数据。
简单测试了下,的确是这样:
|
1
|
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会不会被回收:
|
1
|
jmap -histo:live <pid>
|
结果,发现socket都被回收了。
再看下AbstractPlainSocketImpl的finalize方法:
|
1
2
3
4
5
6
|
/**
* Cleans up if the user forgets to close it.
*/
protected void finalize() throws IOException {
close();
}
|
可以看到socket是会在GC时,被close掉的。
写个程序来测试下:
|
1
2
3
4
5
6
7
8
9
|
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]
|
1
|
ls -al /proc/pid/fd
|
可以看到有像这样的输出:
|
1
|
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没有被回收。
本文比较乱,记录下一些工具和技巧。
netstat统计的tcp连接数与⁄proc⁄pid⁄fd下socket类型fd数量不一致的分析的更多相关文章
- Linux /proc/pid目录下各文件含义
/proc 是一个伪文件系统, 被用作内核数据结构的接口, 而不仅仅是解释说明/dev/kmem. /proc 里的大多数文件都是只读的, 但也可以通过写一些文件来改变内核变量. ( Linux 内核 ...
- Linux /proc/pid目录下文件的含义 (转)
2013-01-16 16:10:36 分类: LINUX attr: 进程的属性 cmdline: 启动进程时执行的命令 cwd: 指向进程当前工作目录的软链 environ: 进程执行时使用的环境 ...
- Linux 系统最大TCP连接数 调优
Linux系统TCP最大连接数 Linux系统可接连接到最大的TCP连接数,高并发情况下可进行扩展加大,最大为65536. 限制最大TCP连接数 修改文件:/etc/sysctl.conf 生效命令: ...
- linux netstat 统计连接数查看
服务器上的一些统计数据 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议连接数ps -ef|grep httpd|wc ...
- linux netstat 统计连接数查看外部(转)
转自:http://boy-liguang.blog.sohu.com/187052443.html linux netstat 统计连接数查看外部 2011-10-11 08:52阅读(16333) ...
- 查看linux中的TCP连接数【转】
转自:http://blog.csdn.net/he_jian1/article/details/40787269 查看linux中的TCP连接数 本文章已收录于: 计算机网络知识库 分类: ...
- Linux中查看TCP连接数
一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议 ...
- 查看linux中的TCP连接数
一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议 ...
- TCP连接数过多问题
在一次生产上线后,发现使用的 8086 端口相关的 TCP 连接数竟然多大 6K+ ,有时候甚至会逼近 1w ,这个数量对于一个只是在内部使用的监控系统来说, 无论如何都是无法接受的, 于是开 ...
随机推荐
- Android -- AudioPlayer
AudioPlayer 主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫.语音) 优点:语音的实时处理,可以用代码实现各种音频的封装 缺点:输出 ...
- (转)【Unity Shaders】Vertex Magic —— 访问顶点颜色
转自:http://blog.csdn.net/candycat1992/article/details/38147767 本系列主要参考<Unity Shaders and Effects C ...
- Camtasia Studio CamStudio如何不录制鼠标
在录制的小窗口中,点击Effects-Options,然后Cursor里面取消勾选Make cursor effects 可能会报错说请选择有效的声音文件 在Sound里面选择一个有效的目录,不能 ...
- SuperMap入门3——Hello World
Hello World程序很重要,对于入门来说,它可以检测我们的环境.配置是否正确,感受程序的易用性等. 添加工具 由于我是使用的VS2017+ SuperMap iObject绿色免安装版,所以新建 ...
- APP测试体系
网上找的图片,总结的很好:
- Direct hosting of SMB over TCP/IP
http://support.microsoft.com/kb/204279 System TipThis article applies to a different version of Wind ...
- 浅谈mysql中utf8和utf8mb4区别
转自:http://ourmysql.com/archives/1402 实践过程中发现有时mysql的字符集会引起故障,所以需要了解下这个知识点. 一.简介 MySQL在5.5.3之后增加了这个u ...
- MySQL事物系列:2:事物的实现
1:事物的隔离性由锁来实现.事物的持久性和事物的原子性通过redo log来实现.事物的一致性通过undo log来实现. redo log恢复提交事物修改的页操作 undo log回滚到行记录某个特 ...
- SSM实战——秒杀系统之高并发优化
一:高并发点 高并发出现在秒杀详情页,主要可能出现高并发问题的地方有:秒杀地址暴露.执行秒杀操作. 二:静态资源访问(页面)优化——CDN CDN,内容分发网络.我们把静态的资源(html/css/j ...
- Linux Shell 下载网站指定文件
Shell脚本,用来从网站下载指定文件名的文件.先判断本地这个文件是否存在,如果存在则忽略,不存在则从远程服务器上下载,下载成功后本地的批次号累加1,然后使用新的批次号继续下载新文件. #!/bin/ ...