gunicorn多进程不死_Flask gevent 多进程WSGI(非gunicorn)

python多进程gevent,Flask gevent multiprocess WSGI,Flask gevent 多进程WSGI,Flask多进程gevent。

题外话:Flask,Instagram据说扛住了上亿日活,以前是Django。其是一个非常优秀的web service 框架,简洁灵活,可以利用大量的第三方组件和模块来快速开发。

如今,Instagram 的总注册用户达到 30 亿,月活用户超过 7 亿 (作为对比,微信最新披露的月活跃用户为 9.38 亿)。而令人吃惊的是,这么高的访问量背后,竟完全是由以速度“慢”著称的 Python + Django 支撑。

时至今日,即使已经拥有超过 30 亿的注册用户。Instagram 仍然是 Python 和 Django 的重度使用者。Instagram 的工程师 Hui Ding 说到: 『一直到用户 ID 已经超过了 32bit int 的限额(约为 20 亿),Django 本身仍然没有成为我们的瓶颈所在。』

flask + gevent + multiprocess + wsgi简介

常常大家都是用gunicorn来解决flask后端部署并发的问题, 然而觉得自启多进程是为更优雅的高并发方式。这样就不需要gunicorn了。也没有额外的第三方部署工作,于是有了以下flask + gevent + multiprocess + wsgi的测试

flask + gevent + multiprocess + wsgi程序代码cppla.py

Python

# coding: utf-8

# code by https://cpp.la, 2020-04-20

# flask + gevent + multiprocess + wsgi

from gevent import monkey

from gevent.pywsgi import WSGIServer

monkey.patch_all()

import datetime

import os

from multiprocessing import cpu_count, Process

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/cppla", methods=['GET'])

def function_benchmark():

return jsonify(

{

"status": "ok",

"time": datetime.datetime.now().strftime('%Y-%m-%d %H:%M'),

"pid": os.getpid()

}

), 200

def run(MULTI_PROCESS):

if MULTI_PROCESS == False:

WSGIServer(('0.0.0.0', 8080), app).serve_forever()

else:

mulserver = WSGIServer(('0.0.0.0', 8080), app)

mulserver.start()

def server_forever():

mulserver.start_accepting()

mulserver._stop_event.wait()

for i in range(cpu_count()):

p = Process(target=server_forever)

p.start()

if __name__ == "__main__":

# 单进程 + 协程

run(False)

# 多进程 + 协程

# run(True)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

# coding: utf-8

# code by https://cpp.la, 2020-04-20

# flask + gevent + multiprocess + wsgi

fromgeventimportmonkey

fromgevent.pywsgiimportWSGIServer

monkey.patch_all()

importdatetime

importos

frommultiprocessingimportcpu_count,Process

fromflaskimportFlask,jsonify

app=Flask(__name__)

@app.route("/cppla",methods=['GET'])

deffunction_benchmark():

returnjsonify(

{

"status":"ok",

"time":datetime.datetime.now().strftime('%Y-%m-%d %H:%M'),

"pid":os.getpid()

}

),200

defrun(MULTI_PROCESS):

ifMULTI_PROCESS==False:

WSGIServer(('0.0.0.0',8080),app).serve_forever()

else:

mulserver=WSGIServer(('0.0.0.0',8080),app)

mulserver.start()

defserver_forever():

mulserver.start_accepting()

mulserver._stop_event.wait()

foriinrange(cpu_count()):

p=Process(target=server_forever)

p.start()

if__name__=="__main__":

# 单进程 + 协程

run(False)

# 多进程 + 协程

# run(True)

测试环境

机器配置

4vCPU

8GB

环境配置

Centos 8

Python 3.6.8

Flask1.1.2

Gevent 1.5.0

压测工具

WRK

4H8G机器

单进程 + 协程 + WSGI

测试结果

QPS : 2361 r/s

该模式启动了一个进程

[root@vm5 ~]# nohup python3 cppla.py &

[1] 9371

[root@vm5 ~]# nohup: ignoring input and appending output to 'nohup.out'

[root@vm5 ~]# ps -ef | grep cppla

root 9371 4184 4 03:33 pts/0 00:00:00 python3 cppla.py

root 9377 4184 0 03:33 pts/0 00:00:00 grep --color=auto cppla

[root@vm5 ~]#

1

2

3

4

5

6

7

8

[root@vm5~]# nohup python3 cppla.py &

[1]9371

[root@vm5~]# nohup: ignoring input and appending output to 'nohup.out'

[root@vm5~]# ps -ef | grep cppla

root93714184403:33pts/000:00:00python3cppla.py

root93774184003:33pts/000:00:00grep--color=autocppla

[root@vm5~]#

测试详情

[root@vm4 wrk]# curl 10.10.10.5:8080/cppla

{"pid":9371,"status":"ok","time":"2020-04-20 04:19"}

[root@vm4 wrk]# curl 10.10.10.5:8080/cppla

{"pid":9371,"status":"ok","time":"2020-04-20 04:19"}

[root@vm4 wrk]# curl 10.10.10.5:8080/cppla

{"pid":9371,"status":"ok","time":"2020-04-20 04:19"}

[root@vm4 wrk]# wrk -t12 -c400 -d30s http://10.10.10.5:8080/cppla

Running 30s test @ http://10.10.10.5:8080/cppla

12 threads and 400 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 164.40ms 21.15ms 515.30ms 80.85%

Req/Sec 199.61 47.81 565.00 70.38%

71237 requests in 30.10s, 10.95MB read

Requests/sec: 2366.72

Transfer/sec: 372.44KB

[root@vm4 wrk]# wrk -t20 -c800 -d30s http://10.10.10.5:8080/cppla

Running 30s test @ http://10.10.10.5:8080/cppla

20 threads and 800 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 329.39ms 93.86ms 1.78s 92.80%

Req/Sec 126.19 80.69 696.00 67.71%

71075 requests in 30.10s, 10.92MB read

Socket errors: connect 0, read 0, write 0, timeout 97

Requests/sec: 2361.39

Transfer/sec: 371.65KB

[root@vm4 wrk]#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

[root@vm4wrk]# curl 10.10.10.5:8080/cppla

{"pid":9371,"status":"ok","time":"2020-04-20 04:19"}

[root@vm4wrk]# curl 10.10.10.5:8080/cppla

{"pid":9371,"status":"ok","time":"2020-04-20 04:19"}

[root@vm4wrk]# curl 10.10.10.5:8080/cppla

{"pid":9371,"status":"ok","time":"2020-04-20 04:19"}

[root@vm4wrk]# wrk -t12 -c400 -d30s http://10.10.10.5:8080/cppla

Running30stest@http://10.10.10.5:8080/cppla

12threadsand400connections

ThreadStatsAvgStdevMax+/-Stdev

Latency164.40ms21.15ms515.30ms80.85%

Req/Sec199.6147.81565.0070.38%

71237requestsin30.10s,10.95MBread

Requests/sec:2366.72

Transfer/sec:372.44KB

[root@vm4wrk]# wrk -t20 -c800 -d30s http://10.10.10.5:8080/cppla

Running30stest@http://10.10.10.5:8080/cppla

20threadsand800connections

ThreadStatsAvgStdevMax+/-Stdev

Latency329.39ms93.86ms1.78s92.80%

Req/Sec126.1980.69696.0067.71%

71075requestsin30.10s,10.92MBread

Socketerrors:connect0,read0,write0,timeout97

Requests/sec:2361.39

Transfer/sec:371.65KB

[root@vm4wrk]#

多进程 + 协程 + WSGI

测试结果

QPS : 7500 r/s

该模式启动了4+1个进程(4vCPU)

[root@vm5 ~]# nohup python3 cppla.py &

[1] 9537

[root@vm5 ~]# nohup: ignoring input and appending output to 'nohup.out'

[root@vm5 ~]# ps -ef | grep cppla

root 9537 4184 5 04:32 pts/0 00:00:00 python3 cppla.py

root 9542 9537 0 04:32 pts/0 00:00:00 python3 cppla.py

root 9543 9537 0 04:32 pts/0 00:00:00 python3 cppla.py

root 9544 9537 0 04:32 pts/0 00:00:00 python3 cppla.py

root 9545 9537 0 04:32 pts/0 00:00:00 python3 cppla.py

root 9547 4184 0 04:32 pts/0 00:00:00 grep --color=auto cppla

[root@vm5 ~]#

1

2

3

4

5

6

7

8

9

10

11

12

[root@vm5~]# nohup python3 cppla.py &

[1]9537

[root@vm5~]# nohup: ignoring input and appending output to 'nohup.out'

[root@vm5~]# ps -ef | grep cppla

root95374184504:32pts/000:00:00python3cppla.py

root95429537004:32pts/000:00:00python3cppla.py

root95439537004:32pts/000:00:00python3cppla.py

root95449537004:32pts/000:00:00python3cppla.py

root95459537004:32pts/000:00:00python3cppla.py

root95474184004:32pts/000:00:00grep--color=autocppla

[root@vm5~]#

测试详情

[root@vm4 wrk]# curl 10.10.10.5:8080/cppla

{"pid":9543,"status":"ok","time":"2020-04-20 04:34"}

[root@vm4 wrk]# curl 10.10.10.5:8080/cppla

{"pid":9542,"status":"ok","time":"2020-04-20 04:34"}

[root@vm4 wrk]# curl 10.10.10.5:8080/cppla

{"pid":9545,"status":"ok","time":"2020-04-20 04:34"}

[root@vm4 wrk]# wrk -t12 -c400 -d30s http://10.10.10.5:8080/cppla

Running 30s test @ http://10.10.10.5:8080/cppla

12 threads and 400 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 56.10ms 15.16ms 187.30ms 85.05%

Req/Sec 590.77 79.95 830.00 67.97%

212138 requests in 30.08s, 32.60MB read

Requests/sec: 7051.89

Transfer/sec: 1.08MB

[root@vm4 wrk]# wrk -t20 -c800 -d30s http://10.10.10.5:8080/cppla

Running 30s test @ http://10.10.10.5:8080/cppla

20 threads and 800 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 101.59ms 40.23ms 337.80ms 66.06%

Req/Sec 394.20 109.48 0.97k 74.47%

235844 requests in 30.10s, 36.25MB read

Requests/sec: 7835.77

Transfer/sec: 1.20MB

[root@vm4 wrk]#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

[root@vm4wrk]# curl 10.10.10.5:8080/cppla

{"pid":9543,"status":"ok","time":"2020-04-20 04:34"}

[root@vm4wrk]# curl 10.10.10.5:8080/cppla

{"pid":9542,"status":"ok","time":"2020-04-20 04:34"}

[root@vm4wrk]# curl 10.10.10.5:8080/cppla

{"pid":9545,"status":"ok","time":"2020-04-20 04:34"}

[root@vm4wrk]# wrk -t12 -c400 -d30s http://10.10.10.5:8080/cppla

Running30stest@http://10.10.10.5:8080/cppla

12threadsand400connections

ThreadStatsAvgStdevMax+/-Stdev

Latency56.10ms15.16ms187.30ms85.05%

Req/Sec590.7779.95830.0067.97%

212138requestsin30.08s,32.60MBread

Requests/sec:7051.89

Transfer/sec:1.08MB

[root@vm4wrk]# wrk -t20 -c800 -d30s http://10.10.10.5:8080/cppla

Running30stest@http://10.10.10.5:8080/cppla

20threadsand800connections

ThreadStatsAvgStdevMax+/-Stdev

Latency101.59ms40.23ms337.80ms66.06%

Req/Sec394.20109.480.97k74.47%

235844requestsin30.10s,36.25MBread

Requests/sec:7835.77

Transfer/sec:1.20MB

[root@vm4wrk]#

协程并发真的很强!4核虚拟机多进程并发高达7000QPS,回头测试一下python协程和golang协程的效率对比。

补充:4核8线程3.6GHZ物理机上多进程并发高达15000QPS

也就是“理想”情况,每秒1w5 QPS,每小时5400万请求。

[root@vm4 wrk]# wrk -t30 -c1000 -d30s http://10.10.10.1:8080/cppla

Running 30s test @ http://10.10.10.1:8080/cppla

30 threads and 1000 connections

Thread Stats Avg Stdev Max +/- Stdev

Latency 67.67ms 18.54ms 312.76ms 81.81%

Req/Sec 489.92 76.58 710.00 68.65%

440105 requests in 30.09s, 68.07MB read

Requests/sec: 14626.25

Transfer/sec: 2.26MB

[root@vm4 wrk]#

1

2

3

4

5

6

7

8

9

10

[root@vm4wrk]# wrk -t30 -c1000 -d30s http://10.10.10.1:8080/cppla

Running30stest@http://10.10.10.1:8080/cppla

30threadsand1000connections

ThreadStatsAvgStdevMax+/-Stdev

Latency67.67ms18.54ms312.76ms81.81%

Req/Sec489.9276.58710.0068.65%

440105requestsin30.09s,68.07MBread

Requests/sec:14626.25

Transfer/sec:2.26MB

[root@vm4wrk]#

你可能感兴趣的:(gunicorn多进程不死)