Gevent是一个基于greenlet的Python的并发框架,以微线程greenlet为核心,使用了epoll事件监听机制以及诸多其余优化而变得高效。python
于greenlet、eventlet相比,性能略低,可是它封装的API很是完善,最赞的是提供了一个monkey类,能够将现有基于Python线程直接转化为greenlet,至关于proxy了一下(打了patch)。web
今天有空就火烧眉毛的试一下效果。服务器
一、安装cookie
Gevent依赖libevent和greenlet,须要分别安装。多线程
1并发 2框架 3socket 4tcp 5性能 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#libevent 1.4.x sudo apt-get install libevent-dev
#python_dev sudo apt-get install python-dev
#easy_install wget -q http://peak.telecommunity.com/dist/ez_setup.py sudo python ./ez_setup.py
#greenlet wget http://pypi.python.org/packages/source/g/greenlet/greenlet-0.3.1.tar.gz#md5=8d75d7f3f659e915e286e1b0fa0e1c4d tar -xzvf greenlet-0.3.1.tar.gz cd greenlet-0.3.1/ sudo python setup.py install
#gevent wget http://pypi.python.org/packages/source/g/gevent/gevent-0.13.6.tar.gz#md5=7c836ce2315d44ba0af6134efbcd38c9 tar -xzvf gevent-0.13.6.tar.gz cd gevent-0.13.6/ sudo python setup.py install |
至此,安装完毕。
二、测试代码:XML-RPC
这里必须使用支持线程的XML-RPC,不然没法发挥gevent的优点!
传统版本:
须要说明的是,这个并不少资料描述的非单线程,而是一个select版本,因此某些时候比线程版本性能好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from SocketServer import ThreadingMixIn from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
from SocketServer import TCPServer
TCPServer.request_queue_size = 10000
#Logic function def add(a, b): return a + b
#Logic function 2 def gen(n): return '0' * n
#create server server = SimpleXMLRPCServer(('', 8080), SimpleXMLRPCRequestHandler,False) server.register_function(add, "add") server.register_function(gen, "gen") server.serve_forever() |
线程版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from SocketServer import ThreadingMixIn from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
#Threaded XML-RPC class TXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): pass
#Logic function def add(a, b): return a + b
#Logic function 2 def gen(n): return "0" * n
#create server server = TXMLRPCServer(('', 8080), SimpleXMLRPCRequestHandler) server.register_function(add, "add") server.register_function(gen, "gen") server.serve_forever() |
三、测试客户端
1 2 3 4 5 6 |
from xmlrpclib import ServerProxy
#Execute RPC server = ServerProxy("http://localhost:8080") #print server.add(3,5) print server.gen(2048) |
四、gevent的monkey包装后的XML-RPC
monkey是非入侵式的patch,只须要显示调用你须要patch的东西就好了,别看我用了三行,其实能够patch_all()的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from SocketServer import ThreadingMixIn from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler from gevent import monkey
#Threaded XML-RPC && Monkey Patch monkey.patch_socket() #Just 2 line! monkey.patch_thread() #Just 3 line! monkey.patch_select() #Just 3 line! class TXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): pass
#Logic function def add(a, b): return a + b
#Logic function 2 def gen(n): return "0" * n
#create server server = TXMLRPCServer(('', 8080), SimpleXMLRPCRequestHandler) server.register_function(add, "add") server.register_function(gen, "gen") server.serve_forever() |
五、测试结果
如今只有一台机器,下午去实验室两台机器跑了之后,放上结果。对gevent仍是比较寄但愿的,但愿不要太差。。
客户端的特殊配置:
echo -e ’1024\t65535′ | sudo tee /proc/sys/net/ipv4/ip_local_port_range
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_syncookies
ulimit -n 10240
服务器端的特殊配置:
echo “10152 65535″ > /proc/sys/net/ipv4/ip_local_port_range
echo 1 | sudo tee /proc/sys/net/ipv4/tcp_tw_recycle
sysctl -w fs.file-max=128000
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.core.somaxconn=250000
sysctl -w net.ipv4.tcp_max_syn_backlog=2500
sysctl -w net.core.netdev_max_backlog=2500
ulimit -n 10240
而后说让你们比较失望的结果:测试效果很是失败,常常出现异常状况,根据个人分析是默认的XML-RPC没有backlog(或者默认过低),致使压力一大,就会fail accept,从而致使RESET(connection refused)。
因此说对monkey的patch不要抱太大但愿,他是和原代码密切相关的。
补充:已经找到修改默认backlog的方法,以下:
1 2 3 |
from SocketServer import TCPServer #修改这个全局变量便可 TCPServer.request_queue_size = 5000 |
固然测试数听说明,不要过度迷恋monkey,那只是个传说~
测试数据:
c=500 n=50000
默认:2845/s, 8M
多线程:1966/s, 51M
gevent:1888/s, 11M
c=1000 n=100000
默认:3096/s, 8M
多线程:1895/s, 52M
gevent:1936/s, 11M
c=5000 n=500000
默认:3009/s, 8M
多线程:失败,没法建立新线程
gevent:1988/s, 11M
c=10000 n=1000000
默认:2883/s, 8M
多线程:失败,没法建立新线程
gevent:1992/s, 20M
monkey的优势就是:省内存,我是和线程的相比。我仔细的分析了一下,XML-RPC使用CPU的比例仍是很大的,相比较于直接http的计算,xmlrpc仍是属于cpu密集型。在这种CPU占用很高,须要反复争夺微greenlet的状况下,gevent并不具备优点。或者从另外一种角度说,测试机不够强大,喂不饱gevent(能够看到,随着并发线程升高,gevent的性能不降反升,而默认的则在不断降低)