近日项目有原来的多线程升级成为多进程模型后,但出现了个问题,在持续运行一天左右系统处理能力开始变慢,并不时打印以下信息:

too many opened files

修改ulimit中open files为10240之后,运行时间稍微变长,但还是会出现该问题。

使用iostat查看统计信息没发现异常,使用netstat 发现系统连接信息如下

#netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 59
CLOSE_WAIT 28199
ESTABLISHED 170

  出现了大量的CLOSE_WAIT,应该是此处导致了fd泄露,抓包分析,结果如下

1 11:22:11.613144 IP 127.0.0.1.55313 > 127.0.0.1.9000: Flags [S], seq 1383947720, win 32792, options [mss 16396,sackOK,TS val 2912656137 ecr 0,nop,wscale 7], length 0
2 11:22:11.613175 IP 127.0.0.1.9000 > 127.0.0.1.55313: Flags [S.], seq 3913709618, ack 1383947721, win 32768, options [mss 16396,sackOK,TS val 2912656137 ecr 2912656137,nop,wscale 7], length 0
3 11:22:11.613192 IP 127.0.0.1.55313 > 127.0.0.1.9000: Flags [.], ack 1, win 257, options [nop,nop,TS val 2912656137 ecr 2912656137], length 0
4 11:22:11.613435 IP 127.0.0.1.55313 > 127.0.0.1.9000: Flags [P.], seq 1:10, ack 1, win 257, options [nop,nop,TS val 2912656137 ecr 2912656137], length 9
5 11:22:11.613446 IP 127.0.0.1.9000 > 127.0.0.1.55313: Flags [.], ack 10, win 256, options [nop,nop,TS val 2912656137 ecr 2912656137], length 0
6 11:22:11.632594 IP 127.0.0.1.9000 > 127.0.0.1.55313: Flags [P.], seq 1:10, ack 10, win 256, options [nop,nop,TS val 2912656156 ecr 2912656137], length 9
7 11:22:11.632650 IP 127.0.0.1.55313 > 127.0.0.1.9000: Flags [.], ack 10, win 257, options [nop,nop,TS val 2912656156 ecr 2912656156], length 0
8 11:22:11.632732 IP 127.0.0.1.55313 > 127.0.0.1.9000: Flags [F.], seq 10, ack 10, win 257, options [nop,nop,TS val 2912656156 ecr 2912656156], length 0
9 11:22:11.672056 IP 127.0.0.1.9000 > 127.0.0.1.55313: Flags [.], ack 11, win 256, options [nop,nop,TS val 2912656196 ecr 2912656156], length 0

可以看出,在该次第通信中,前期数据包交互一切正常,但在连接结束之后client端发送了fin报文,而server没有发送Fin包,导致大量的tcp连接停留在close_wai状态,close_wait的分析参考这里http://blog.chinaunix.net/uid-9688646-id-3469570.html

追查代码是很确定调用了close函数关闭socket

因为之前多线程时候没有类似的问题,所以考虑是不是引入多进程之后导致的问题

为此编写多进程版本的socket模型,查看其数据包交互模型,参考网上一哥们的代码,如下

 1 #multiprocessserver.py
2 import multiprocessing
3 import socket
4
5 def handle(connection, address):
6 import logging
7 logging.basicConfig(level=logging.DEBUG)
8 logger = logging.getLogger("process-%r" % (address,))
9 try:
10 logger.debug("Connected %r at %r", connection, address)
11 while True:
12 data = connection.recv(1024)
13 if data == "":
14 logger.debug("Socket closed remotely")
15 break
16 logger.debug("Received data %r", data)
17 connection.sendall(data)
18 logger.debug("Sent data")
19 except:
20 logger.exception("Problem handling request")
21 finally:
22 logger.debug("Closing socket")
23 connection.close()
24
25 class Server(object):
26 def __init__(self, hostname, port):
27 import logging
28 self.logger = logging.getLogger("server")
29 self.hostname = hostname
30 self.port = port
31
32 def start(self):
33 self.logger.debug("listening")
34 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
35 self.socket.bind((self.hostname, self.port))
36 self.socket.listen(1)
37
38 while True:
39 conn, address = self.socket.accept()
40 self.logger.debug("Got connection")
41 process = multiprocessing.Process(target=handle, args=(conn, address))
42 process.daemon = True
43 process.start()
44 self.logger.debug("Started process %r", process)
45
46 if __name__ == "__main__":
47 import logging
48 logging.basicConfig(level=logging.DEBUG)
49 server = Server("0.0.0.0", 9000)
50 try:
51 logging.info("Listening")
52 server.start()
53 except:
54 logging.exception("Unexpected exception")
55 finally:
56 logging.info("Shutting down")
57 for process in multiprocessing.active_children():
58 logging.info("Shutting down process %r", process)
59 process.terminate()
60 process.join()
61 logging.info("All done")
 1 #mulclient.py
2 import socket
3
4 if __name__ == "__main__":
5 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
6 sock.connect(("localhost", 9000))
7 data = "some data"
8 sock.sendall(data)
9 result = sock.recv(1024)
10 print result
11 sock.close()

验证了上面的假设

结论:

python2.6.6版本的多进程multiprocessing在关闭socket时是有问题的,会导致close函数无效从而引发大量close_wait状态的tcp链接

python multiprocess不能完全关闭socket的验证的更多相关文章

  1. python异常处理、反射、socket

    一.isinstance 判断对象是否为类的实例 n1 = print isinstance(n1,int) class A: pass class B(A): pass b= B() print i ...

  2. 关闭SSL证书验证

    转载 Python3之关闭SSL证书验证 转载 Python requests 移除SSL认证,控制台输出InsecureRequestWarning取消方法 报错信息: Traceback (mos ...

  3. python 网络编程 TCP/IP socket UDP

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

  4. python第八周:socket网络编程

    1.socket网络编程 1.1概念: 网络套接字是跨计算机网络的连接的端点.今天,计算机之间的大多数通信都基于互联网协议;因此大多数网络套接字都是Internet套接字.更准确地说,套接字是一个句柄 ...

  5. Eclipse关闭XML文件验证的方法

    XML的编写是否符合规范,可以通过XML Schema或DTD进行验证,但有时候电脑本来就很卡,而且XML的某些错误并未导致程序无法运行的情况下,暂时关闭XML的验证也算不错的选择. 如web.xml ...

  6. Eclipse关闭XML文件验证的方法,解决xml警告

    XML的编写是否符合规范,可以通过XML Schema或DTD进行验证,但有时候电脑本来就很卡,而且XML的某些错误并未导致程序无法运行的情况下,暂时关闭XML的验证也算不错的选择. 如web.xml ...

  7. python学习之路-9 socket网络编程

    socket基础 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. so ...

  8. 给Extjs的window弹窗的关闭事件添加验证

    问题:我想在window点击右上角叉关闭时添加一些验证,来确定是否关闭? 实现: 首先想到的是拦截window的关闭事件,在它关闭前添加验证,但是有一个问题是,如何阻止它的关闭和组织关闭后,如何让它再 ...

  9. c# 关闭socket的标准方法

    aSocket.Shutdown(SocketShutdown.Both); aSocket.Close(); c#关闭socket时,单独使用socket.close()通常会造成资源提前被释放,应 ...

随机推荐

  1. jQuery/CSS3大屏下拉菜单 自定义子菜单内容

    这是一款样式很酷的jQuery/CSS3下拉菜单,首先这款CSS3菜单是宽屏的,主要是下拉菜单非常大气,更重要的是,下拉菜单的内容可以自己定义,也就是说,下拉菜单中可以定义菜单.图片等HTML元素,是 ...

  2. Codeforces Round #375 (Div. 2) ABCDE

    A - The New Year: Meeting Friends 水 #include<iostream> #include<algorithm> using namespa ...

  3. 【转】Maven实战(四)---多模块项目---JBOSS部署问题

    原文出自于:http://blog.csdn.net/liutengteng130/article/details/41622681      感谢! 这几天在搭框架中仅仅是JBOSS就遇到了很多问题 ...

  4. 关于scrollTop的那些事

    大家在实际项目中,应该是要经常用到scrollTop的,它表示的是可视窗口距离页面顶部的距离,这个scrollTop是可读写的,所以可以用来做页面滚动. 但是大家或多或少遇到一些浏览器兼容问题,为什么 ...

  5. 搭建nodejs环境推荐用两个工具:nvm和npm

    nvm 是 nodejs version manager 的简称,即:nodejs版本管理npm 是 nodejs package manager 的简称,即:nodejs模块管理 有了这两个工具,管 ...

  6. POJ1328Radar Installation(贪心)

    对于每一个点,可以找到他在x轴上的可行区域,这样的话就变为了对区间的贪心. #include<iostream> #include<stdio.h> #include<s ...

  7. CodeForces 589A Email Aliases (匹配,水题)

    题意:给定于所有的邮箱,都是由login@domain这样的形式构成,而且字符都是不区分大小写的. 我们有一种特殊类型的邮箱——@bmail.com, 这种邮箱除了不区分大小写外—— 1,'@'之前的 ...

  8. UVaLive 7267 Mysterious Antiques in Sackler Museum (if-else,枚举)

    题意:给定四个矩形,要求从中选出三个,能不能拼成一个矩形. 析:说到这个题,我还坑了队友一次,读题读错了,我直接看的样例,以为是四个能不能组成,然后我们三个就拼命想有什么简便方法,后来没办法了,直接暴 ...

  9. C#中的where从句

    C#中的where从句 2011-07-03 13:07OrphousV | 分类:C#/.NET | 浏览8443次 能解释一下下面两段代码中where的作用吗?using System;publi ...

  10. foxpro常用命令

    Visual FoxPro原名FoxBase,最初是由美国Fox Software公司于1988年推出的数据库产品,在DOS上运行,与xBase系列兼容.FoxPro是FoxBase的加强版,最高版本 ...