標籤:
ss
用來顯示處於活動狀態的通訊端資訊。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也可以正常運行,只是效率會變得稍慢。
選項
-h:顯示協助資訊;-V:顯示指令版本資訊;-n:不解析服務名稱,以數字方式顯示;-a:顯示所有的通訊端;-l:顯示處於監聽狀態的通訊端;-o:顯示計時器資訊;-m:顯示通訊端的記憶體使用量情況;-p:顯示使用通訊端的進程資訊;-i:顯示內部的TCP資訊;-4:只顯示ipv4的通訊端;-6:只顯示ipv6的通訊端;-t:只顯示tcp通訊端;-u:只顯示udp通訊端;-d:只顯示DCCP通訊端;-w:僅顯示RAW通訊端;-x:僅顯示UNIX域通訊端。
執行個體
顯示TCP串連
[[email protected] ~]# ss -t -aState Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 0 *:3306 *:* LISTEN 0 0 *:http *:* LISTEN 0 0 *:ssh *:* LISTEN 0 0 127.0.0.1:smtp *:* ESTAB 0 0 112.124.15.130:42071 42.156.166.25:http ESTAB 0 0 112.124.15.130:ssh 121.229.196.235:33398
顯示 Sockets 摘要
[[email protected] ~]# ss -sTotal: 172 (kernel 189)TCP: 10 (estab 2, closed 4, orphaned 0, synrecv 0, timewait 0/0), ports 5Transport Total ip IPv6* 189 - - RAW 0 0 0 UDP 5 5 0 TCP 6 6 0 INET 11 11 0 FRAG 0 0 0
列出當前的established, closed, orphaned and waiting TCP sockets
查看進程使用的socket
[[email protected] ~]# ss -plState Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::ssh :::* users:(("sshd",1292,4))LISTEN 0 128 *:ssh *:* users:(("sshd",1292,3))LISTEN 0 128 127.0.0.1:ipp *:* users:(("cupsd",1165,7))LISTEN 0 128 ::1:ipp :::* users:(("cupsd",1165,6))LISTEN 0 128 *:32957 *:* users:(("rpc.statd",1104,9))LISTEN 0 128 :::57637 :::* users:(("rpc.statd",1104,11))LISTEN 0 80 :::mysql :::* users:(("mysqld",1528,17))LISTEN 0 128 *:6379 *:* users:(("redis-server",1672,5))LISTEN 0 128 :::6379 :::* users:(("redis-server",1672,4))LISTEN 0 128 :::sunrpc :::* users:(("rpcbind",1084,11))LISTEN 0 128 *:sunrpc *:* users:(("rpcbind",1084,8))LISTEN 0 128 *:http *:* users:(("nginx",1685,13),("nginx",3698,13),("nginx",3699,13))
找出開啟通訊端/連接埠應用程式
[[email protected] ~]# ss -pl | grep 33060 0 *:3306 *:* users:(("mysqld",1718,10))
參考linux命令網,同時可以看營運存留時間的解釋https://www.ttlsa.com/linux-command/ss-replace-netstat/
關於Recv-Q和Send-Q狀態
在網上一搜大部分的說法都是這樣的:
recv-Q 表示網路接收隊列
表示收到的資料已經在本地接收緩衝,但是還有多少沒有被進程取走,recv()
如果接收隊列Recv-Q一直處於阻塞狀態,可能是遭受了拒絕服務 denial-of-service 攻擊。
send-Q 表示網路發送隊列
對方沒有收到的資料或者說沒有Ack的,還是本地緩衝區.
如果發送隊列Send-Q不能很快的清零,可能是有應用向外發送資料包過快,或者是對方接收資料包不夠快。
這兩個值通常應該為0,如果不為0可能是有問題的。packets在兩個隊列裡都不應該有堆積狀態。可接受短暫的非0情況。
對於上邊的說法不能說錯,但最起碼不完全正確,我感覺下邊的才是正解,來自:TCP queue 的一些問題
- 當 client 通過 connect 向 server 發出 SYN 包時,client 會維護一個 socket 等待隊列,而 server 會維護一個 SYN 隊列
- 此時進入半連結的狀態,如果 socket 等待隊列滿了,server 則會丟棄,而 client 也會由此返回 connection time out;只要是 client 沒有收到 SYN+ACK,3s 之後,client 會再次發送,如果依然沒有收到,9s 之後會繼續發送
- 半串連 syn 隊列的長度為 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) 決定
- 當 server 收到 client 的 SYN 包後,會返回 SYN, ACK 的包加以確認,client 的 TCP 協議棧會喚醒 socket 等待隊列,發出 connect 調用
- client 返回 ACK 的包後,server 會進入一個新的叫 accept 的隊列,該隊列的長度為 min(backlog, somaxconn),預設情況下,somaxconn 的值為 128,表示最多有 129 的 ESTAB 的串連等待 accept(),而 backlog 的值則由 int listen(int sockfd, int backlog) 中的第二個參數指定,listen 裡面的 backlog 的含義請看這裡。需要注意的是,一些 Linux 的髮型版本可能存在對 somaxcon 錯誤 truncating 方式。
- 當 accept 隊列滿了之後,即使 client 繼續向 server 發送 ACK 的包,也會不被相應,此時,server 通過 /proc/sys/net/ipv4/tcp_abort_on_overflow 來決定如何返回,0 表示直接丟丟棄該 ACK,1 表示發送 RST 通知 client;相應的,client 則會分別返回 read timeout 或者 connection reset by peer。上面說的只是些理論,如果伺服器不及時的調用 accept(),當 queue 滿了之後,伺服器並不會按照理論所述,不再對 SYN 進行應答,返回 ETIMEDOUT。根據這篇文檔的描述,實際情況並非如此,伺服器會隨機的忽略收到的 SYN,建立起來的串連數可以無限的增加,只不過用戶端會遇到延時以及逾時的情況。
可以看到,整個 TCP stack 有如下的兩個 queue:
1. 一個是 half open(syn queue) queue(max(tcp_max_syn_backlog, 64)),用來儲存 SYN_SENT 以及 SYN_RECV 的資訊。
2. 另外一個是 accept queue(min(somaxconn, backlog)),儲存 ESTAB 的狀態,但是調用 accept()。
注意,之前我對 Recv-Q/Send-Q 的理解有些誤差,使用 ss 擷取到的 Recv-Q/Send-Q 在 LISTEN 狀態以及非 LISTEN 狀態所表達的含義是不同的。從 tcp_diag.c 源碼中可以看到二者的區別:
LISTEN 狀態: Recv-Q 表示的當前等待服務端調用 accept 完成三向交握的 listen backlog 數值,也就是說,當用戶端通過 connect() 去串連正在 listen() 的服務端時,這些串連會一直處於這個 queue 裡面直到被服務端 accept();Send-Q 表示的則是最大的 listen backlog 數值,這就就是上面提到的 min(backlog, somaxconn) 的值。
其餘狀態: 非 LISTEN 狀態之前理解的沒有問題。Recv-Q 表示 receive queue 中的 bytes 數量;Send-Q 表示 send queue 中的 bytes 數值。
ss命令和Recv-Q和Send-Q狀態