ss命令和Recv-Q和Send-Q狀態

ssmysql

用來顯示處於活動狀態的套接字信息。ss命令能夠用來獲取socket統計信息,它能夠顯示和netstat相似的內容。但ss的優點在於它可以顯示更多更詳細的有關TCP和鏈接狀態的信息,並且比netstat更快速更高效。linux

當服務器的socket鏈接數量變得很是大時,不管是使用netstat命令仍是直接cat /proc/net/tcp,執行速度都會很慢。可能你不會有切身的感覺,但請相信我,當服務器維持的鏈接達到上萬個的時候,使用netstat等於浪費 生命,而用ss纔是節省時間。nginx

天下武功惟快不破。ss快的祕訣在於,它利用到了TCP協議棧中tcp_diagtcp_diag是一個用於分析統計的模塊,能夠得到Linux 內核中第一手的信息,這就確保了ss的快捷高效。固然,若是你的系統中沒有tcp_diagss也能夠正常運行,只是效率會變得稍慢。redis

 

選項sql

-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鏈接網絡

[root@localhost ~]# ss -t -a
State       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 摘要運維

[root@localhost ~]# ss -s
Total: 172 (kernel 189)
TCP:   10 (estab 2, closed 4, orphaned 0, synrecv 0, timewait 0/0), ports 5

Transport 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 socketsssh

查看進程使用的socketsocket

[root@localhost ~]# ss -pl
State       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))

找出打開套接字/端口應用程序

[root@localhost ~]# ss -pl | grep 3306
0      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 的一些問題

 

  1. 當 client 經過 connect 向 server 發出 SYN 包時,client 會維護一個 socket 等待隊列,而 server 會維護一個 SYN 隊列
  2. 此時進入半連接的狀態,若是 socket 等待隊列滿了,server 則會丟棄,而 client 也會由此返回 connection time out;只要是 client 沒有收到 SYN+ACK,3s 以後,client 會再次發送,若是依然沒有收到,9s 以後會繼續發送
  3. 半鏈接 syn 隊列的長度爲 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)  決定
  4. 當 server 收到 client 的 SYN 包後,會返回 SYN, ACK 的包加以確認,client 的 TCP 協議棧會喚醒 socket 等待隊列,發出 connect 調用
  5. client 返回 ACK 的包後,server 會進入一個新的叫 accept 的隊列,該隊列的長度爲 min(backlog, somaxconn),默認狀況下,somaxconn 的值爲 128,表示最多有 129 的 ESTAB 的鏈接等待 accept(),而 backlog 的值則由 int listen(int sockfd, int backlog) 中的第二個參數指定,listen 裏面的 backlog 的含義請看這裏。須要注意的是,一些 Linux 的髮型版本可能存在對 somaxcon 錯誤 truncating 方式
  6. 當 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 數值。

相關文章
相關標籤/搜索