python Gevent – 高性能的Python併發框架

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的性能不降反升,而默認的則在不斷降低)

相關文章
相關標籤/搜索