从下面这个图来看,netstat和ss都是网络相关的监控,netstat在协议栈中每一层都可以做监控统计:TCP、路由表、网络接口、协议等,但是在Linux中,netstat已经不为推荐,取而代之的是ss。

general 网络监控 网络监控图解_general 网络监控

 

1)netstat参数和使用

常用参数-anplt

-a 显示所有活动的连接以及本机侦听的TCP、UDP端口

-l 显示监听的server port

-n 直接使用IP地址,不通过域名服务器

-p 正在使用Socket的程序PID和程序名称

-r 显示路由表

-t 显示TCP传输协议的连线状况

-u 显示UDP传输协议的连线状况

-w 显示RAW传输协议的连线状况

general 网络监控 网络监控图解_TCP_02

 

在Linux下,raw格式的数据通常可以通过/proc/net/dev获得。在Windows平台,netstat信息可以通过IP Helper API的GetTcpTable和GetUdpTable函数获得。

2)ss(socket statistics)参数和使用

常用参数和netstat类似,如-anp

-a显示所有的sockets

-l显示正在监听的

-n显示数字IP和端口,不通过域名服务器

-p显示使用socket的对应的程序

-t只显示TCP sockets

-u只显示UDP sockets

-4 -6 只显示v4或v6V版本的sockets

-s打印出统计信息。这个选项不解析从各种源获得的socket。对于解析/proc/net/top大量的sockets计数时很有效

-0 显示PACKET sockets

-w 只显示RAW sockets

-x只显示UNIX域sockets

-r尝试进行域名解析,地址/端口

general 网络监控 网络监控图解_IP_03

 

统计信息:

general 网络监控 网络监控图解_UDP_04

 

ss还可以使用IP地址筛选如ss src xxxxIP:port,以及使用端口筛选ss dport OP PORT,OP支持的运算符有le ge eq ne lt gt。

 

3)原理对比

ss比netstat快的主要原因是,netstat是遍历/proc下面每个PID目录,ss直接读/proc/net下面的统计信息。所以ss执行的时候消耗资源以及消耗的时间都比netstat少很多。

当服务器的socket连接数量非常大时(如上万个),无论是使用netstat命令还是直接cat /proc/net/tcp执行速度都会很慢,相比之下ss可以节省很多时间。ss快的秘诀在于,它利用了TCP协议栈中tcp_diag,这是一个用于分析统计的模块,可以获得Linux内核中的第一手信息。如果系统中没有tcp_diag,ss也可以正常运行,只是效率会变得稍微慢但仍然比netstat要快。

根据博客的测试

同样的大量socket连接情况下,netstat和ss获取同样的统计数据时的耗时,ss明显比netstat少很多。我们也可以简单测试一下在少数socket情况下(基本无差别):

time netstat -atn以及time ss -atn对比

general 网络监控 网络监控图解_IP_05

 

netstat属于net-tools工具集,ss属于ipoute工具集。替换方案如下:

general 网络监控 网络监控图解_general 网络监控_06

【场景一:我想查看当前服务器的网络连接统计】

$ss-s
Total:295(kernel312)
TCP:  48(estab1,closed31,orphaned0,synrecv0,timewait0/0),ports13
 
TransportTotal    IP        IPv6
*        312      -        -
RAW      0        0        0
UDP      2        2        0
TCP      17        12        5
INET      19        14        5
FRAG      0        0        0

在服务器产生大量sockets连接时,我们会使用这个命令在做宏观统计。

【场景二:我想查看所有打开的网络端口】

$ ss -l
Recv-Q Send-Q           Local Address:Port               Peer Address:Port
0      128                         :::webcache                      :::*
0      128                         :::http                         :::*
0      128                         :::snapenetio                      :::*
0      128                          *:snapenetio                       *:*
0      50                           *:8531                          *:*
0      9                           :::ftp                          :::*
0      9                            *:ftp                           *:*
0      128                          *:ddi-tcp-1                       *:*
0      100                        ::1:smtp                         :::*
0      100                  127.0.0.1:smtp                          *:*
0      128                          *:8541                          *:*
0      128                  127.0.0.1:entextxid                       *:*
0      50                           *:12421                         *:*
0      10                           *:amqp                          *:*
0      128                          *:12521                         *:*
0      50                           *:mysql                         *:*

果使用-pl参数的话,则会列出具体的程序名称。你会在输出中看到类似于这样的内容:

("nginx",15786,6)

场景三:我想查看这台服务器上所有的socket连接】

很简单,直接使用-a选项即可列出所有网络连接。

 

#ss -a

如果只想查看TCP sockets,那么使用-ta选项;
如果只想查看UDP sockets,那么使用-ua选项;
如果只想查看RAW sockets,那么使用-wa选项;
如果只想查看UNIX sockets,那么使用-xa选项。