21 服務端 socket 開發之多線程和 gevent 框架並發測試[python 語言]

測試下多線程和 gevent 在 socket 服務端的小包表現能力,測試的方法不太嚴謹,有點屬於自娛自樂,要是有問題之處,請大家噴之!

每個連接都特意堵塞了 0.5 秒鐘!

圖片 21.1 pic

在大批量 tcp 測試下,threading 的開銷越來越大,所以造成了在並發數加大的情況下,出現 threading 崩潰的情況!gevent 是 libevent 和協程的融合,一個線程裡面都可以跑超多的協程! 利用 libevent 做 io 堵塞的調度,gevent 體系下,同一時間只有一個任務在運行!

先來測試下多線程: 我們就不加線程池了

 #!/usr/bin/env python # -*- coding: utf-8 -*- #xiaorui.ccimport sysimport socketimport timeimport threading #xiaorui.ccdef threads(port):    s = socket.socket    s.bind((\'0.0.0.0\', port))    s.listen(500)    while True:cli, addr = s.acceptt = threading.Thread(target=handle_request, args=(cli, time.sleep))t.daemon = Truet.startdef handle_request(s, sleep):    try:s.recv(1024)sleep(0.5)   s.send(\'\'\'http/1.0 200 OK  Hello World! \'\'\')s.shutdown(socket.SHUT_WR)print \'.\',    except Exception, ex:print ex    finally:sys.stdout.flushs.closeif __name__ == \'__main__\':    threads(4444)  

用 threading 跑 socket,每個連接堵塞的時間是 0.5

time ab -n 10000 -c 500 http://127.0.0.1:4444/This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsCompleted 10000 requestsFinished 10000 requestsServer Software:Server Hostname:127.0.0.1Server Port:    4444Document Path:  /Document Length:0 bytesConcurrency Level:      500Time taken for tests:   11.123 secondsComplete requests:      10000Failed requests:0Write errors:   0Total transferred:      470000 bytesHTML transferred:       0 bytesRequests per second:    899.01 [#/sec] (mean)Time per request:       556.166 [ms] (mean)Time per request:       1.112 [ms] (mean, across all concurrent requests)Transfer rate:  41.26 [Kbytes/sec] receivedConnection Times (ms)      min  mean[+/-sd] median   maxConnect:0   33 177.0      0    1000Processing:   500  508  33.9    501    1132Waiting:      500  508  33.9    501    1132Total:500  541 201.8    501    2132Percentage of the requests served within a certain time (ms)  50%    501  66%    501  75%    502  80%    505  90%    522  95%    532  98%   1534  99%   1722 100%   2132 (longest request)real    0m11.145suser    0m0.210ssys     0m0.961s  

圖片 21.2 pic

加到 800 的時候~

圖片 21.3 pic

gevent:

 #xiaorui.ccimport sysimport socketimport timeimport geventfrom gevent import socketdef server(port):    s = socket.socket    s.bind((\'0.0.0.0\', port))    s.listen(500)    while True:cli, addr = s.acceptgevent.spawn(handle_request, cli, gevent.sleep)def handle_request(s, sleep):    try:data=s.recv(1024)sleep(0.5)s.send(\'\'\'http/1.0 200 OK  Hello World! this is xiaorui.cc !!!\'\'\')print datarequest_string = "GET %s HTTP/1.1rnHost: %srnrnServer: xiaorui.ccn" %(\'index.html\', \'127.0.0.1\')     s.send(request_string)s.shutdown(socket.SHUT_WR)print \'.\',『be killed』    except Exception, ex:print ex    finally:s.closeif __name__ == \'__main__\':    server(7777)  

gevent 跑 socket 服務:

並發數值是 500 的時候!

time ab -n 10000 -c 500 http://127.0.0.1:7777/This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsCompleted 10000 requestsFinished 10000 requestsServer Software:Server Hostname:127.0.0.1Server Port:    7777Document Path:  /Document Length:0 bytesConcurrency Level:      500Time taken for tests:   11.312 secondsComplete requests:      10000Failed requests:0Write errors:   0Total transferred:      20000 bytesHTML transferred:       0 bytesRequests per second:    884.04 [#/sec] (mean)Time per request:       565.584 [ms] (mean)Time per request:       1.131 [ms] (mean, across all concurrent requests)Transfer rate:  1.73 [Kbytes/sec] receivedConnection Times (ms)      min  mean[+/-sd] median   maxConnect:0   44 202.7      0    1001Processing:   500  513  10.1    511     707Waiting:      500  513  10.1    511     707Total:500  557 204.1    512    1525Percentage of the requests served within a certain time (ms)  50%    512  66%    515  75%    517  80%    519  90%    531  95%    552  98%   1521  99%   1523 100%   1525 (longest request)real    0m11.334suser    0m0.159ssys     0m0.730s 

圖片 21.4 pic

服務端看到的信息都是正常的!

圖片 21.5 pic

並發是 1000 的時候:

time ab -n 10000 -c 1000 http://127.0.0.1:7777/This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsCompleted 10000 requestsFinished 10000 requestsServer Software:Server Hostname:127.0.0.1Server Port:    7777Document Path:  /Document Length:0 bytesConcurrency Level:      1000Time taken for tests:   7.406 secondsComplete requests:      10000Failed requests:0Write errors:   0Total transferred:      20000 bytesHTML transferred:       0 bytesRequests per second:    1350.22 [#/sec] (mean)Time per request:       740.623 [ms] (mean)Time per request:       0.741 [ms] (mean, across all concurrent requests)Transfer rate:  2.64 [Kbytes/sec] receivedConnection Times (ms)      min  mean[+/-sd] median   maxConnect:0  175 491.7      0    3000Processing:   500  520  17.7    515     707Waiting:      500  520  17.7    515     707Total:500  695 492.5    517    3521Percentage of the requests served within a certain time (ms)  50%    517  66%    523  75%    538  80%    569  90%   1515  95%   1530  98%   1539  99%   3514 100%   3521 (longest request)real    0m7.428suser    0m0.208ssys     0m0.741s  

當並發到 1500 的時候:

time ab -n 10000 -c 1500 http://127.0.0.1:7777/This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 127.0.0.1 (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsCompleted 10000 requestsFinished 10000 requestsServer Software:Server Hostname:127.0.0.1Server Port:    7777Document Path:  /Document Length:0 bytesConcurrency Level:      1500Time taken for tests:   5.290 secondsComplete requests:      10000Failed requests:0Write errors:   0Total transferred:      20000 bytesHTML transferred:       0 bytesRequests per second:    1890.27 [#/sec] (mean)Time per request:       793.536 [ms] (mean)Time per request:       0.529 [ms] (mean, across all concurrent requests)Transfer rate:  3.69 [Kbytes/sec] receivedConnection Times (ms)      min  mean[+/-sd] median   maxConnect:0  214 404.9      1    1003Processing:   500  522  23.0    514     716Waiting:      500  522  23.0    514     716Total:500  736 406.7    520    1712Percentage of the requests served within a certain time (ms)  50%    520  66%    558  75%    602  80%   1506  90%   1526  95%   1531  98%   1535  99%   1548 100%   1712 (longest request)real    0m5.313suser    0m0.275ssys     0m0.763s  

出現了少量的報錯:

圖片 21.6 pic

gevent 可以加個隊列,來限制協程的數目,但是數目限制了,雖然穩定了,但是並發數上不去。

from gevent.pool import Poolpool = Pool(N)  

這裡測試有點簡單,雖然已經安排了連接的堵塞,但是畢竟不符合業務。 有時間把後端的任務改成才 mongodb 取數據 !

本文出自 「峰雲,就她了。」 博客,謝絕轉載!

《Python實戰-從菜鳥到大牛的進階之路》