Home | 簡體中文 | 繁體中文 | 雜文 | 打賞(Donations) | ITEYE 博客 | OSChina 博客 | Facebook | Linkedin | 知乎專欄 | Search | About

14.2. ss - another utility to investigate sockets

		
ss是Socket Statistics的縮寫
    ss命令可以用來獲取socket統計信息,它可以顯示和netstat類似的內容;但ss的優勢在於它能夠顯示更多更詳細的有關TCP和連接狀態的信息,而且比netstat更快速更高效.
    
    當伺服器的socket連接數量變得非常大時,無論是使用netstat命令還是直接cat /proc/net/tcp,執行速度都會很慢;ss快的秘訣在於,它利用到了TCP協議棧中 tcp_diag . tcp_diag是一個用於分析統計的模組, 用netfilter來獲取第Linux內核中第一手的信息,這就確保了ss的快捷高效;如果你的系統中沒有tcp_diag,ss也可以正常運行,只是效率會變得稍慢.
    
    netstat命令是net-tools工具集中的一員,而ss命令是iproute工具集中的一員.
    yum install iproute iproute-doc


#### ss過濾器

ss的過濾器分為兩種:
     state
         狀態:established,syn-sent,syn-recv,fin-wait-1,fin-wait-2,time-wait,closed,close-wait,last-ack,listen,closing
         除了這13種狀態之外,還有幾個聚類的狀態:
             all – for all the states
             bucket – 顯示狀態為maintained as minisockets,如:time-wait和syn-recv
             big – 和bucket相反
             connected – 除了listen and closed的所有狀態
             synchronized – 所有已連接的狀態除了syn-sent
     addr+port
         地址和連接埠可以使用表達式,類似於tcpdump中的用法,關鍵字有:
             dst ADDRESS_PATTERN – matches remote address and port
             src ADDRESS_PATTERN – matches local address and port
             dport RELOP PORT – compares remote port to a number
             sport RELOP PORT – compares local port to a number
             autobound – checks that socket is bound to an ephemeral port

#### ss usage

ss [ OPTIONS ] [ FILTER ]
        OPTIONS:
            -p 顯示每個進程的名字和pid
            -s 列出當前socket詳細信息
            -n 不解析服務名稱
            -r 解析主機名
            -a 顯示所有套接字(sockets)
            -o 顯示計時器信息(timer)
            -l 顯示監聽狀態的套接字(sockets)
            -e 顯示詳細的套接字(sockets)信息
            -m 顯示套接字(sockets)的內存使用情況
            -i 顯示 TCP內部信息
            -4 僅顯示IPv4的套接字(sockets)
            -6 僅顯示IPv6的套接字(sockets)
            -0 顯示 PACKET 套接字(sockets)
            -t 僅顯示 TCP套接字(sockets)
            -u 僅顯示 UCP套接字(sockets)
            -d 僅顯示 DCCP套接字(sockets)
            -w 僅顯示 RAW套接字(sockets)
            -x 僅顯示 Unix套接字(sockets)
            -f --family=FAMILY  顯示 FAMILY類型的套接字(sockets),FAMILY可選,支持 unix, inet, inet6, link, netlink
            -D --diag=FILE     將原始TCP套接字(sockets)信息轉儲到檔案
            -F --filter=FILE   從檔案中都去過濾器信息 FILTER := [ state TCP-STATE ] [ EXPRESSION ]

#### Recv And Send

[root@netkiller ~]# ss -anp | column -c1
State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port
LISTEN     0      128               127.0.0.1:9000                     *:*      users:(("php-fpm",1481,9),("php-fpm",1482,0),("php-fpm",1483,0),("php-fpm",1484,0),("php-fpm",1485,0),("php-fpm",1486,0),("php-fpm",1487,0),("php-fpm",1488,0),("php-fpm",1489,0),("php-fpm",1490,0),("php-fpm",1491,0))
LISTEN     0      50                        *:3306                     *:*      users:(("mysqld",2680,11))
LISTEN     0      128                       *:443                      *:*      users:(("nginx",1743,8),("nginx",1744,8),("nginx",1745,8))
LISTEN     0      128              10.1.17.17:2812                     *:*      users:(("monit",2030,6))
TIME-WAIT  0      0                 127.0.0.1:43251            127.0.0.1:80
TIME-WAIT  0      0                 127.0.0.1:43248            127.0.0.1:80
ESTAB      0      0                10.1.17.17:22              10.1.17.18:51752  users:(("sshd",3122,3))
ESTAB      0      0                10.1.17.17:22              10.1.20.70:51531  users:(("sshd",19093,3))

處于LISTEN狀態的socket:
    Recv-Q表示了current listen backlog隊列元素數目(等待用戶調用accept的完成3次握手的socket)
    Send-Q表示了listen socket最大能容納的backlog.這個數目由listen時指定,且不能大於 /proc/sys/net/ipv4/tcp_max_syn_backlog;
    
對於非LISTEN socket:
    Recv-Q表示了receive queue中的位元組數目(等待接收的下一個tcp段的序號-尚未從內核空間copy到用戶空間的段最前面的一個序號)
    Send-Q表示發送queue中容納的位元組數(已加入發送隊列中最後一個序號-輸出段中最早一個未確認的序號)


#### Sockets State
>1 Listen


[root@netkiller ~]# ss -lnp | column -c1
State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port
LISTEN     0      128               127.0.0.1:9000                     *:*      users:(("php-fpm",1481,9),("php-fpm",1482,0),("php-fpm",1483,0),("php-fpm",1484,0),("php-fpm",1485,0),("php-fpm",1486,0),("php-fpm",1487,0),("php-fpm",1488,0),("php-fpm",1489,0),("php-fpm",1490,0),("php-fpm",1491,0))
LISTEN     0      50                        *:3306                     *:*      users:(("mysqld",2680,11))
LISTEN     0      50                        *:3307                     *:*      users:(("mysqld",2564,11))

>2 Established


[root@netkiller ~]# ss -onp state established | column -c1
Recv-Q Send-Q             Local Address:Port               Peer Address:Port
0      0                     10.1.17.17:22                   10.1.17.18:51752  timer:(keepalive,70min,0) users:(("sshd",3122,3))
0      0                     10.1.17.17:22                   10.1.20.70:51531  timer:(keepalive,69min,0) users:(("sshd",19093,3))

>3 Sockets Summary


[root@netkiller ~]# ss -s
Total: 93 (kernel 150)
TCP:   106 (estab 10, closed 88, orphaned 0, synrecv 0, timewait 88/0), ports 41

Transport Total     IP        IPv6
*	  150       -         -
RAW	  0         0         0
UDP	  1         1         0
TCP	  18        18        0
INET	  19        19        0
FRAG	  0         0         0

>4 Expand


1 顯示所有狀態為established的ssh連接
[root@netkiller ~]# ss -o state established '( dport = :ssh or sport = :ssh )'
Recv-Q Send-Q                                      Local Address:Port                                          Peer Address:Port
0      0                                              10.1.17.17:ssh                                             10.1.17.18:51752    timer:(keepalive,109min,0)
0      0                                              10.1.17.17:ssh                                             10.1.20.70:51531    timer:(keepalive,103min,0)

#### ***timer user mem rto*** 

------在另外一個終端執行 ssh 10.1.2.103-----
然後在本終端執行如下命令
[root@netkiller ~]# ss -eimpn '( dport = :22 )' -o
State      Recv-Q Send-Q                                                          Local Address:Port                                                            Peer Address:Port
ESTAB      0      0                                                                   10.1.2.23:44107                                                             10.1.2.103:22     timer:(keepalive,28min,0) users:(("ssh",9545,4)) ino:21970248 sk:ffff88013c2e5900
	 mem:(r0,w0,f4096,t0) sack cubic wscale:7,8 rto:203 rtt:3.25/1.75 ato:40 cwnd:10 send 35.9Mbps rcv_rtt:33427 rcv_space:113592
	 
------在另外一個終端執行 telnet 27.111.200.86 15672-----
然後在本終端執行如下命令
[root@netkiller ~]# ss -eimpn '( dport = :15672 )' -o
State      Recv-Q Send-Q                                                          Local Address:Port                                                            Peer Address:Port
ESTAB      0      2                                                                   10.1.2.23:57531                                                          27.111.200.86:15672  timer:(on,614ms,0) users:(("telnet",10163,4)) ino:21983807 sk:ffff8800378ba040
	 mem:(r0,w554,f3542,t0) sack cubic wscale:7,8 cwnd:10 rcv_space:14600

> timer


-o 顯示計時器信息(timer),linux對一個tcp socket總共有7個定時器,通過4個timer實現
    通過icsk_retransmit_timer實現的重傳定時器,零窗口探測定時器;
    通過sk_timer實現的連接建立定時器,保活定時器和FIN_WAIT_2定時器;
    通過icsk_delack_timer實現的延時ack定時器以及TIME_WAIT定時器.
    
timer 這個輸出描述的是tcp socket上的定時器
timer 的輸出含義就是(類型,過期時間,重試次數)
    off: 當前socket沒有timer
    on: 重傳timer
    keepalive:連接建立timer or fin_wait_2 timer or 保活timer;具體是那個timer,可以根據連接的狀態來確定.
    timewait: TIME_WAITtimer
    persist:零窗口探測timer 

> user


ss -p 輸出users項裡會出現三個參數:
    第一個是進程名
    第二個為pid
    第三項該進程檔案描述符的使用數量

> mem


mem:(r0,w554,f3542,t0)
r  the read (inbound) buffer
w  the write (outbound) buffer
f  the "forward allocated memory" (memory available to the socket)
t  the transmit queue (stuff waiting to be sent or waiting on an ACK)

> socket information


sack cubic wscale
rto
rtt
cwnd
send
rcv_space

#### Notice
>1 ss process name and pid


only name

ss -tp | grep -v Recv-Q | sed -e 's/.*users:(("//' -e 's/".*$//' | sort | uniq

only  pid
[root@netkiller ~]# ss -tp | grep -v Recv-Q | sed -e 's/.*users:((.*",//' -e 's/,.*$//'  | sort | uniq

name  and pid
# ss -tp | grep -v Recv-Q | sed -e 's/.*users:(("\(.*\)",\(.*\),.*$/\1:\2/' | sort | uniq
f_e_related_dat:4695
mysqld:4289
salt-minion:4001
sshd:25161