用ss来代替netstat

ss是Socket Statistics的缩写。
顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。

为什么要替代

当服务器的socket连接数量变得非常大时,无论是使用netstat命令还是直接cat /proc/net/tcp,执行速度都会很慢。可能你不会有切身的感受,但请相信我,当服务器维持的连接达到上万个的时候,使用netstat等于浪费生命,而用ss才是节省时间。

ss快的原因,在于用到了TCP协议栈中tcp_diag。tcp_diag是一个用于分析统计的模块,可以获得Linux内核中第一手的信息,这就确保了ss的快捷高效。当然,如果你的系统中没有tcp_diag,ss也可以正常运行,只是效率会变得稍慢。(但仍然比netstat要快。)

为了加速让你去用ss,下面给了一些具体数据。当服务器维持9万个socket连接,Admin需要计算具体的连接数量时,不同情况的耗时如下:

1
2
3
4
5
6
$ netstat -at | wc
# 55.73s
$ ss -atr | wc
# 16.33s
$ ss -atr | wc
# 1.27s (use tcp_diag)

几乎所有的Linux系统都会默认包含netstat命令,但并非所有系统都会默认包含ss命令。

因为netstat命令是net-tools工具集中的一员:

1
2
$ rpm -q net-tools
net-tools-1.60-114.el6.x86_64

而ss命令是iproute工具集中的一员:

1
2
$ rpm -q iproute
iproute-2.6.32-54.el6.x86_64

如果你无法使用ss命令,那么可能是缺少了iproute,需要安装一下:

1
# yum install iproute iproute-doc

net-tools是一套标准的Unix网络工具,用于配置网络接口、设置路由表信息、管理ARP表、显示和统计各类网络信息等等,但是遗憾的是,这个工具自2001年起便不再更新和维护了。

接替net-tools任务的便是iproute,这是一套可以支持IPv4/IPv6网络的用于管理TCP/UDP/IP网络的工具集,这套工具由Stephen Hemminger负责维护和升级,目前的大版本号是2。

从某种意义上说,iproute工具集几乎可以替代掉net-tools工具集,具体的替代方案是这样的:

用途 net-tool iproute2
地址和链路配置 ifconfig ip addr/ip link
路由表 route ip route
邻居 arp ip neigh
VLAN vconfig ip link
隧道 iptunnel ip tunnel
组播 ipmaddr ip maddr
统计 netstat ss

版本和帮助

想获得ss命令的帮助信息和版本信息,都非常简单,随便敲都能猜到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ ss -h
Usage: ss [ OPTIONS ]
ss [ OPTIONS ] [ FILTER ]
-h, --help this message
-V, --version output version information
-n, --numeric don't resolve service names
-r, --resolve resolve host names
-a, --all display all sockets
-l, --listening display listening sockets
-o, --options show timer information
-e, --extended show detailed socket information
-m, --memory show socket memory usage
-p, --processes show process using socket
-i, --info show internal TCP information
-s, --summary show socket usage summary

-4, --ipv4 display only IP version 4 sockets
-6, --ipv6 display only IP version 6 sockets
-0, --packet display PACKET sockets
-t, --tcp display only TCP sockets
-u, --udp display only UDP sockets
-d, --dccp display only DCCP sockets
-w, --raw display only RAW sockets
-x, --unix display only Unix domain sockets
-f, --family=FAMILY display sockets of type FAMILY

-A, --query=QUERY, --socket=QUERY
QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]

-D, --diag=FILE Dump raw information about TCP sockets to FILE
-F, --filter=FILE read filter information from FILE
FILTER := [ state TCP-STATE ] [ EXPRESSION ]
$ ss -V
ss utility, iproute2-ss091226

ss选项统计

ss的选项既不多也不复杂,除去非功能性选项(-h/-V)外,ss共有22个选项。

实操一波来看看ss有多香。

查看当前服务器的网络连接统计

1
2
3
4
5
6
7
8
9
10
11
$ ss -s
Total: 307 (kernel 375)
TCP: 108 (estab 99, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 68

Transport Total IP IPv6
* 375 - -
RAW 0 0 0
UDP 3 3 0
TCP 108 108 0
INET 111 111 0
FRAG 0 0 0

查看所有监听中的网络端口

1
2
3
4
5
6
7
8
9
10
$ ss -l
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 512 192.168.195.19:16000 *:*
LISTEN 0 128 *:10050 *:*
LISTEN 0 512 127.0.0.1:16007 *:*
LISTEN 0 512 192.168.195.19:16200 *:*
LISTEN 0 512 127.0.0.1:16009 *:*
LISTEN 0 512 192.168.195.19:16010 *:*
LISTEN 0 512 192.168.195.19:16333 *:*
LISTEN 0 128 *:ssh *:*

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

1
LISTEN     0      128                 :::http                 :::*        users:(("httpd",1188,4),("httpd",2151,4),("httpd",10213,4),("httpd",10214,4),("httpd",10215,4),("httpd",10216,4),("httpd",10217,4),("httpd",10218,4),("httpd",10219,4),("httpd",10220,4),("httpd",11724,4),("httpd",18632,4))

从中可以知道,某个socket连接是属于httpd的,PID是1188/2151/10213等等。

查看这台服务器上所有的socket连接

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

1
2
3
4
$ ss -a
State Recv-Q Send-Q Local Address:Port Peer Address:Port
……

可以配合使用tuwx等参数,例如只查看udp。

1
2
3
4
5
$ ss -au
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 192.168.195.19:ntp *:*
UNCONN 0 0 127.0.0.1:ntp *:*
UNCONN 0 0 *:ntp *:*