背景由于目前在用的Flask项目涉及到一部分依赖Windows的处理,还无法迁移到linux平台,那么在windows环境下,要怎么部署呢?思路根据Flask官网介绍,由于Flask内置的服务器性能不佳,推荐的主要的部署方式有如下几种:mod_wsgi (Apache)独立 WSGI 容器GunicornTornadoGeventuWSGIFastCGICGI上述这些部署方式,仅Tornado是支持在windows情况下部署的,配合上Nginx可以达到比较好的效果。可已参考Nginx与tornado框架的并发评测。但是在实际使用中发现,tornado 的稳定性虽然很高,但是在tornado上部署Flask,并不会有异步的效果。实际上还是单进程阻塞运行的,即使在Flask中配置了threaded = True也无法实现多线程使用。Flask多线程情况配置启用多线程:# manage.pyfrom flask_script import Serverserver = Server(host=“0.0.0.0”, threaded=True)在Flask中配置两条测试路由import time@main.route(’/test’)def maintest(): return ‘hello world’ @main.route(’/sleep’)def mainsleep(): time.sleep(60) return ‘wake up’先用浏览器访问\sleep:随即立刻访问\test:可见两次访问是不同的线程处理的,不会出现堵塞的情况。tornado + Flask多线程情况使用tornado托管:from tornado.wsgi import WSGIContainerfrom tornado.httpserver import HTTPServerfrom tornado.ioloop import IOLoopfrom yourapplication import apphttp_server = HTTPServer(WSGIContainer(app))http_server.listen(5000)IOLoop.instance().start()先用浏览器访问\sleep:随即立刻访问\test:可以发现,虽然tornado框架是支持异步的,但是由于实际上后台的处理是同步的,从而无法实现异步的处理的效果。如果想后台的处理也异步,则需要直接使用tornado来开发。那么为什么使用tornado来托管flask呢?Tornado 是一个开源的可伸缩的、非阻塞式的 web 服务器和工具集,它驱动了FriendFeed 。因为它使用了 epoll 模型且是非阻塞的,它可以处理数以千计的并发固定连接,这意味着它对实时 web 服务是理想的。把 Flask 集成这个服务是直截了当的根据官网描述,其实也是为了弥足flask自带服务器不稳定的问题。Flask高并发下的表现使用tsung进行压测,压力500:Namehighest 10sec meanlowest 10sec meanHighest RateMean RateMeanCountconnect34.30 msec31.91 msec506 / sec356.60 / sec33.19 msec103908page0.42 sec0.29 sec505 / sec356.32 / sec0.39 sec103782request0.42 sec0.29 sec505 / sec356.32 / sec0.39 sec103782session1mn 24sec10.64 sec11.4 / sec1.21 / sec14.24 sec362CodeHighest RateMean RateTotal number200505 / sec356.32 / sec104792NameHighest RateTotal numbererror_abort0.5 / sec1error_abort_max_conn_retries11.7 / sec362error_connect_econnrefused58.6 / sec1667可见,在500的并发下,效果不佳,有很多的链接拒绝。Flask + Nginx在高并发下的表现使用tsung进行压测,压力500:Namehighest 10sec meanlowest 10sec meanHighest RateMean RateMeanCountconnect0.20 sec30.95 msec1810.5 / sec626.43 / sec0.11 sec189853page0.68 sec0.17 sec1810.1 / sec625.72 / sec0.40 sec189581request0.68 sec0.17 sec1810.1 / sec625.72 / sec0.40 sec189581CodeHighest RateMean RateTotal number200906.4 / sec196.08 / sec606895021443.9 / sec430.02 / sec129006NameHighest RateTotal numbererror_abort0.5 / sec1情况差不多,Flask服务器表现还算稳定,那么尝试增加后台Flask服务器数量(通过多端口实现):python manage.py runserver –port=8001python manage.py runserver –port=8002python manage.py runserver –port=8003python manage.py runserver –port=8004使用tsung进行压测,压力500,4个Flask服务器:Namehighest 10sec meanlowest 10sec meanHighest RateMean RateMeanCountconnect0.18 sec32.57 msec3510.1 / sec639.92 / sec0.11 sec195154page0.49 sec85.30 msec3512.1 / sec639.07 / sec0.35 sec194856request0.49 sec85.30 msec3512.1 / sec639.07 / sec0.35 sec194856CodeHighest RateMean RateTotal number2003510.1 / sec639.50 / sec194986NameHighest RateTotal numbererror_abort0.333333333333333 / sec1这个效果妥妥的。使用tsung进行压测,压力1000,4个Flask服务器:Namehighest 10sec meanlowest 10sec meanHighest RateMean RateMeanCountconnect0.20 sec32.63 msec2983.8 / sec492.94 / sec98.56 msec150793page0.57 sec90.00 msec2976.4 / sec491.31 / sec0.40 sec150275request0.57 sec90.00 msec2976.4 / sec491.31 / sec0.40 sec150275CodeHighest RateMean RateTotal number2002981.4 / sec488.92 / sec14955650292.5 / sec4.02 / sec925NameHighest RateTotal numbererror_abort0.333333333333333 / sec1开始有一些502的超时错误了。使用tsung进行压测,压力1000,4个tornado服务器:Namehighest 10sec meanlowest 10sec meanHighest RateMean RateMeanCountconnect0.18 sec86.24 msec2052.1 / sec693.82 / sec0.14 sec208786page0.52 sec0.24 sec2060.7 / sec693.34 / sec0.45 sec208606request0.52 sec0.24 sec2060.7 / sec693.34 / sec0.45 sec208606CodeHighest RateMean RateTotal number2002056.6 / sec693.67 / sec208703在并发1000的情况下,是否使用tornado托管Flask效果差不多。结论根据上述测试,直接使用Flask服务器的话,由于并发处理较弱,会有各种超时或者连接拒绝的错误。通过搭配Nginx来进行缓冲,通过增加后端服务器数来提供并发处理量。所以最终选择了Nginx+后台4个Flask服务器的方式。由于目前Flask项目全体用户只有几千,目前并发情况很低,该方式完全满足使用。如果在更大型项目中,并发上万,建议还是考虑想办法迁移至Liunx环境,通过官方建议的方式部署。