背景
由于目前在用的Flask项目涉及到一部分依赖Windows的处理,还无法迁移到linux平台,那么在windows
环境下,要怎么部署呢?
思路
根据Flask
官网介绍,由于Flask
内置的服务器性能不佳,推荐的主要的部署方式有如下几种:
- mod_wsgi (Apache)
- 独立 WSGI 容器
- Gunicorn
- Tornado
- Gevent
- uWSGI
- FastCGI
- CGI
上述这些部署方式,仅Tornado
是支持在windows
情况下部署的,配合上Nginx
可以达到比较好的效果。可已参考Nginx与tornado框架的并发评测。
但是在实际使用中发现,tornado
的稳定性虽然很高,但是在tornado
上部署Flask
,并不会有异步的效果。实际上还是单进程阻塞运行的,即使在Flask
中配置了threaded = True
也无法实现多线程使用。
Flask多线程情况
配置启用多线程:
1 | # manage.py |
在Flask
中配置两条测试路由
1 | import time |
先用浏览器访问\sleep
:
随即立刻访问\test
:
可见两次访问是不同的线程处理的,不会出现堵塞的情况。
tornado + Flask多线程情况
使用tornado
托管:
1 | from tornado.wsgi import WSGIContainer |
先用浏览器访问\sleep
:
随即立刻访问\test
:
可以发现,虽然tornado
框架是支持异步的,但是由于实际上后台的处理是同步的,从而无法实现异步的处理的效果。如果想后台的处理也异步,则需要直接使用tornado
来开发。
那么为什么使用tornado
来托管flask
呢?
Tornado 是一个开源的可伸缩的、非阻塞式的 web 服务器和工具集,它驱动了FriendFeed 。因为它使用了 epoll 模型且是非阻塞的,它可以处理数以千计的并发固定连接,这意味着它对实时 web 服务是理想的。把 Flask 集成这个服务是直截了当的
根据官网描述,其实也是为了弥足flask
自带服务器不稳定的问题。
Flask高并发下的表现
使用tsung
进行压测,压力500:
Name | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean | Count |
---|---|---|---|---|---|---|
connect | 34.30 msec | 31.91 msec | 506 / sec | 356.60 / sec | 33.19 msec | 103908 |
page | 0.42 sec | 0.29 sec | 505 / sec | 356.32 / sec | 0.39 sec | 103782 |
request | 0.42 sec | 0.29 sec | 505 / sec | 356.32 / sec | 0.39 sec | 103782 |
session | 1mn 24sec | 10.64 sec | 11.4 / sec | 1.21 / sec | 14.24 sec | 362 |
Code | Highest Rate | Mean Rate | Total number |
---|---|---|---|
200 | 505 / sec | 356.32 / sec | 104792 |
Name | Highest Rate | Total number |
---|---|---|
error_abort | 0.5 / sec | 1 |
error_abort_max_conn_retries | 11.7 / sec | 362 |
error_connect_econnrefused | 58.6 / sec | 1667 |
可见,在500的并发下,效果不佳,有很多的链接拒绝。
Flask + Nginx在高并发下的表现
- 使用
tsung
进行压测,压力500:
Name | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean | Count |
---|---|---|---|---|---|---|
connect | 0.20 sec | 30.95 msec | 1810.5 / sec | 626.43 / sec | 0.11 sec | 189853 |
page | 0.68 sec | 0.17 sec | 1810.1 / sec | 625.72 / sec | 0.40 sec | 189581 |
request | 0.68 sec | 0.17 sec | 1810.1 / sec | 625.72 / sec | 0.40 sec | 189581 |
Code | Highest Rate | Mean Rate | Total number |
---|---|---|---|
200 | 906.4 / sec | 196.08 / sec | 60689 |
502 | 1443.9 / sec | 430.02 / sec | 129006 |
Name | Highest Rate | Total number |
---|---|---|
error_abort | 0.5 / sec | 1 |
情况差不多,Flask
服务器表现还算稳定,那么尝试增加后台Flask
服务器数量(通过多端口实现):
1 | python manage.py runserver --port=8001 |
- 使用
tsung
进行压测,压力500,4个Flask
服务器:
Name | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean | Count |
---|---|---|---|---|---|---|
connect | 0.18 sec | 32.57 msec | 3510.1 / sec | 639.92 / sec | 0.11 sec | 195154 |
page | 0.49 sec | 85.30 msec | 3512.1 / sec | 639.07 / sec | 0.35 sec | 194856 |
request | 0.49 sec | 85.30 msec | 3512.1 / sec | 639.07 / sec | 0.35 sec | 194856 |
Code | Highest Rate | Mean Rate | Total number |
---|---|---|---|
200 | 3510.1 / sec | 639.50 / sec | 194986 |
Name | Highest Rate | Total number |
---|---|---|
error_abort | 0.333333333333333 / sec | 1 |
这个效果妥妥的。
- 使用
tsung
进行压测,压力1000,4个Flask
服务器:
Name | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean | Count |
---|---|---|---|---|---|---|
connect | 0.20 sec | 32.63 msec | 2983.8 / sec | 492.94 / sec | 98.56 msec | 150793 |
page | 0.57 sec | 90.00 msec | 2976.4 / sec | 491.31 / sec | 0.40 sec | 150275 |
request | 0.57 sec | 90.00 msec | 2976.4 / sec | 491.31 / sec | 0.40 sec | 150275 |
Code | Highest Rate | Mean Rate | Total number |
---|---|---|---|
200 | 2981.4 / sec | 488.92 / sec | 149556 |
502 | 92.5 / sec | 4.02 / sec | 925 |
Name | Highest Rate | Total number |
---|---|---|
error_abort | 0.333333333333333 / sec | 1 |
开始有一些502
的超时错误了。
- 使用
tsung
进行压测,压力1000,4个tornado
服务器:
Name | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean | Count |
---|---|---|---|---|---|---|
connect | 0.18 sec | 86.24 msec | 2052.1 / sec | 693.82 / sec | 0.14 sec | 208786 |
page | 0.52 sec | 0.24 sec | 2060.7 / sec | 693.34 / sec | 0.45 sec | 208606 |
request | 0.52 sec | 0.24 sec | 2060.7 / sec | 693.34 / sec | 0.45 sec | 208606 |
Code | Highest Rate | Mean Rate | Total number |
---|---|---|---|
200 | 2056.6 / sec | 693.67 / sec | 208703 |
在并发1000的情况下,是否使用tornado
托管Flask
效果差不多。
结论
根据上述测试,直接使用Flask
服务器的话,由于并发处理较弱,会有各种超时或者连接拒绝的错误。通过搭配Nginx
来进行缓冲,通过增加后端服务器数来提供并发处理量。
所以最终选择了Nginx
+后台4个Flask
服务器的方式。由于目前Flask
项目全体用户只有几千,目前并发情况很低,该方式完全满足使用。
如果在更大型项目中,并发上万,建议还是考虑想办法迁移至Liunx
环境,通过官方建议的方式部署。