如何选择Flask应用的多种部署方案?
摘要:前言 开发调试阶段,运行 Flask 的方式多直接使用 app.run(),但 Flask 内置的 WSGI Server 的性能并不高。对于生产环境,一般使用 gunicorn。如果老项目并不需要多高的性能,而且用了很多单进程内的共享变量
前言
开发调试阶段,运行 Flask 的方式多直接使用 app.run(),但 Flask 内置的 WSGI Server 的性能并不高。对于生产环境,一般使用 gunicorn。如果老项目并不需要多高的性能,而且用了很多单进程内的共享变量,使用 gunicorn 会影响不同会话间的通信,那么也可以试试直接用 gevent。
在 Docker 流行之前,生产环境部署 Flask 项目多使用 virtualenv + gunicorn + supervisor。Docker 流行之后,部署方式就换成了 gunicorn + Docker。如果没有容器编排服务,后端服务前面一般还会有个 nginx 做代理。如果使用 Kubernetes,一般会使用 service + ingress(或 istio 等)。
运行方式
Flask 内置 WSGI Server
开发阶段一般使用这种运行方式。
# main.py
from flask import Flask
from time import sleep
app = Flask(__name__)
@app.get("/test")
def get_test():
sleep(0.1)
return "ok"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=10000)
运行:
python main.py
gevent
使用 gevent 运行 Flask,需要先安装 gevent
python -m pip install -U gevent
代码需要稍作修改。
需要注意 monkey.patch_all() 一定要写在入口代码文件的最开头部分,这样 monkey patch 才能生效。
# main.py
from gevent import monkey
monkey.patch_all()
import time
from flask import Flask
from gevent.pywsgi import WSGIServer
app = Flask(__name__)
@app.get("/test")
def get_test():
time.sleep(0.1)
return "ok"
if __name__ == "__main__":
server = WSGIServer(("0.0.0.0", 10000), app)
server.serve_forever()
运行
python main.py
gunicorn + gevent
如果现有项目大量使用单进程内的内存级共享变量,贸然使用 gunicorn 多 worker 模式可能会导致数据访问不一致的问题。
同样需要先安装依赖。
python -m pip install -U gunicorn gevent
不同于单独使用 gevent,这种方式不需要修改代码,gunicorn 会自动注入 gevent 的 monkey patch。
gunicorn 可以在命令行配置启动参数,但个人一般习惯在 gunicorn 的配置文件内配置启动参数,这样可以动态设置一些配置,而且可以修改日志格式。
