利用 Xpocket 的 ss 插件获取 socket 信息原创
xpocket目前集成了ss插件,ss用来替代netstat的,可以用来获取socket统计信息,它可以显示和netstat类似的内容。 但ss的优势在于它能够显示更多更详细的有关tcp和连接状态的信息,而且比netstat更快速更高效。当然netstat 也有自己的特点,netstat 除了显示socket信息外还可以显示接口 snmp等统计信息。
ss比netstat快的主要原因是,netstat需要遍历/proc下面每个pid目录,而ss利用了tcp协议栈中tcp_diag。所以ss执行的时候消耗资源以及消耗的时间都比netstat少很多。当服务器的socket连接数量非常大时,无论是使用netstat命令需要遍历的目录非常多导致执行速度都会很慢,相比之下ss则不存在这个问题速度还是非常的快。
我们看一下我们使用ss插件的-ti参数查看一下tcp的详细信息:
可以看到很多tcp连接的详细信息,包括 cwnd 也就是慢启动窗口, tcp的rtt 时间等等, 其中的recv-q 和 send-q 可以看到tcp服务的负载状况,
对于listen状态下的tcp来说 send-q 和 recv-q 跟普通的 estab 状态下的有所区别:
recv-q:表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值。
send-q: 表示的则是最大的 listen backlog 数值
在tcp服务发生无法建连时可以通过查看该listen状态下的 recv-q 数量是否异常, 我们通过一个python程序模拟一下:
#! /usr/bin/python
# a simple tcp server
import socket,os,time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 9000))
sock.listen(2)
while True:
time.sleep(6000)
connection,address = sock.accept()
print 'new connect: ',connection.fileno() ,address
buf = connection.recv(10240)
print 'get data len=',len(buf) ,'data: '+ buf
connection.send(buf)
connection.close()
print 'connect close'
可以看到tcp的连接队列被设置成 2
我们使用 nc 127.0.0.1 9000 命令连接该服务,在第三个连接时,Ncat: Connection reset by peer 提示服务端拒绝了该请求。
通常来说对于listen socket recv-q 里一般是0的状态,否则说明accept里有新的请求未及处理,出现积压,特殊情况下 recv-q 被占满导致新的请求无法建立。recv-q 是观察服务端健康状态一个非常关键的指标。
ss 插件在定位tcp 服务问题时非常方便好用,可以打印出tcp连接的详细信息,服务端的负载状态,tcp客户端建连状态等等, 可以统计close_wait, time_wait 等状态tcp 连接的数量,确定系统服务状态是否正常。