分析关于close_wait过多对系统造成的影响

别的不说,先上代码(^-^代码:谁要上我?)

# socket_server.py
import socket,sys
ser=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ser.bind(('192.168.199.1',int(sys.argv[1])))
ser.listen(5)
while 1:
    client,addr=ser.accept()
    client.close() #这里当客户的连接服务器之后  服务器立即断开

# socket_client.py
import socket,time,sys
def client():
    mysocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    mysocket.connect(('192.168.199.1',int(sys.argv[1])))
    return mysocket
socket_list=[]
try:
    while True:
        socket_list.append(client()) # 客户端保持连接并创建新的连接
except Exception as err:
    print(err)
    print("Conn count:%d" % len(socket_list))
time.sleep(1000)

这两段程序就是模拟产生大量close_wait

# 在IP为192.168.199.1的服务器上执行
[root@server ~]# python socket_server.py 8001


# 在IP为192.168.199.74的终端上执行
[root@client ~]# python socket_client.py 8001 &
[1] 2046
[root@client ~]# [Errno 99] Cannot assign requested address
Conn count:28232

[root@client ~]# telnet 192.168.199.1 8001
Trying 192.168.199.1...
telnet: connect to address 192.168.199.1: Cannot assign requested address

我们可以发现,在程序结束之前,我们是连不上这个端口了。

注: 这里之前是最大1024个,报错信息:socket.error: [Errno 24] Too many open files,原因是因为每个程序默认只能打开1024个文件描述符. 执行ulimit -n 65535临时增加程序允许打开的文件描述符数量。

那么问题来了:

  • 为什么是28232个连接?
    通过查阅资料,原因是因为内核参数的限制,可通过修改此参数来增大最大连接数
    因为客户端每次连接服务器,本地都会打开一个端口,而这个端口会从这个内核参数限制的范围来取,取完了就不能再连接了

    [root@client ~]# sysctl -a |grep port_range
    net.ipv4.ip_local_port_range = 32768    60999
    

然后再继续探究

# 在IP为192.168.199.1的服务器上执行
[root@server ~]# python socket_server.py 8001
[root@server ~]# python socket_server.py 8002
[root@server ~]# python socket_server.py 8003

# 在IP为192.168.199.74的终端上执行
[root@client ~]# free -h
             total       used       free     shared    buffers     cached
Mem:          1.9G       242M       1.6G       508K       9.1M        63M
-/+ buffers/cache:       170M       1.7G
Swap:         2.0G         0B       2.0G

[root@client ~]# python socket_client.py 8001 &
[1] 2076
[Errno 99] Cannot assign requested address
Conn count:28232

[root@client ~]# python socket_client.py 8002 &
[2] 2077
[Errno 99] Cannot assign requested address
Conn count:28232

[root@client ~]# python socket_client.py 8003 &
[3] 2078
[Errno 99] Cannot assign requested address
Conn count:28232
[root@client ~]# free -h
             total       used       free     shared    buffers     cached
Mem:          1.9G       695M       1.2G       548K        10M        65M
-/+ buffers/cache:       619M       1.3G
Swap:         2.0G         0B       2.0G
[root@client ~]# netstat -an|wc -l
84787
[root@client ~]# netstat -an|grep 33768
tcp        1      0 192.168.199.74:33768        192.168.199.1:8001          CLOSE_WAIT  
tcp        1      0 192.168.199.74:33768        192.168.199.1:8002          CLOSE_WAIT  
tcp        1      0 192.168.199.74:33768        192.168.199.1:8003          CLOSE_WAIT

[root@client ~]# iostat -x 1
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    0.00    0.00    0.00  100.00

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
vda               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
dm-1              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00

通过htop查看三个python进程每个使用23M的内存,算下来系统因创建连接开销为450M,估算出每个连接会占用5KB的内存。检查cpu和磁盘io都没有受到影响
但是问题又来了

  • 为什么同时开了3个相同的端口,明明端口未释放但是又能通过这个端口创建了一个新的连接
    (问题待解决)

综上所述close_wait对系统影响:
1. 占用系统内存
2. 如果连接数满了就不能对相应的对段端口创建连接了
3. 假设你的程序会去连接另一个服务,而未正常关闭,那么可能导致你的程序超过最大连接数的时候报异常,引起连锁反应甚至导致程序崩溃
4. 网上有说法可能会导致系统扫描端口连接,影响cpu,但是测试中未发现这个问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值