Python中如何解决简单Flask API服务器程序阻塞的问题?多端口多实例、wsgi,还是Flask程序自身能解决?
Python 里用 Flask 写的 API 服务器端,程序就是对收到的用户名密码连接到本地 MySQL 查询一下是否正确然后返回授权信息。虽然正常情况下能很快处理一个请求,但是测试了下发现 Flask 的 API 函数是阻塞执行的。。在处理一个请求时其它的请求竟然就那么停着。。
搜了下资料,是不是要加什么 uwsgi 的,或者是那个 return jsonify() 函数可以做什么文章,异步返回吗?或者是在多个 Tcp 端口上开启多个 flask 实例,然后 Nginx 反向代理。。
小白求教。。
Python中如何解决简单Flask API服务器程序阻塞的问题?多端口多实例、wsgi,还是Flask程序自身能解决?
flask 默认的 web server 是单线程的?这个还不是很清楚,不过默认的 web server 一般不推荐生产环境使用吧。具体用哪个 web server 我也不是很明白,楼下推荐一下。至于要不要 Nginx 来做个集群负载就看需要了。。
简单来说,Flask自带的开发服务器是单线程的,处理请求时会阻塞。生产环境不能用它。核心解决方案是搭配一个WSGI应用服务器,比如Gunicorn或uWSGI。
Flask本身只是个Web框架,不是全功能的服务器。开发服务器(app.run())性能很差,只能用于调试。要解决阻塞,你需要一个能处理并发请求的WSGI服务器。这些服务器会管理一个工作者进程/线程池,一个请求阻塞时,其他工作者可以继续处理新请求。
最直接的方法:用Gunicorn
假设你的主程序文件叫 app.py,里面创建了Flask应用实例 app。
-
安装Gunicorn:
pip install gunicorn -
用Gunicorn运行你的应用:
# 最基本用法,启动多个工作者进程 gunicorn -w 4 -b 0.0.0.0:5000 app:app-w 4:启动4个工作进程(根据CPU核心数调整)。-b 0.0.0.0:5000:绑定到所有网络接口的5000端口。app:app:第一个app是模块名(文件名app.py),第二个app是Flask应用实例的变量名。
代码示例对比: 这是你的阻塞版开发服务器:
# app.py (不要在生产环境这样运行)
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
# 一个模拟的耗时操作,会阻塞整个开发服务器
import time
time.sleep(5)
return 'Hello after 5 seconds!'
if __name__ == '__main__':
app.run(debug=True) # 单进程、单线程,会阻塞
改用Gunicorn后,你不再需要 app.run() 这行。直接通过上面的Gunicorn命令启动。这样,当一个工作者进程在处理sleep(5)时,其他空闲的工作者可以立刻响应新的请求,从而实现并发。
关于你提到的其他方案:
- 多端口多实例:这是用Nginx等反向代理在多个Flask进程间做负载均衡,是另一种扩容思路,但每个Flask实例内部可能还是阻塞的(除非你也用了WSGI服务器)。它通常和WSGI服务器结合使用,而不是替代。
- Flask程序自身:Flask 2.0支持
async视图,配合asyncio服务器(如Hypercorn、Uvicorn)可以更好地处理I/O密集型阻塞(如网络请求、数据库查询)。但对于纯CPU计算阻塞或sleep,还是需要多进程/多线程。
一句话总结:用Gunicorn这类WSGI服务器替代Flask自带的开发服务器。
能参考下项目不?我是返回路径,多线程的。没有你那个现象,搜我贴有代码
LZ 下一个问题是如何改 mysql 配置让支持 1w 并发查询
Flask 自带的服务器只是方便调试的,文档说了不适合用来生产环境。
用 gunicorn 或者 uwsgi 就好。
新鲜热乎的文章在 ,Ubuntu 上使用 uWSGI 和 Nginx 部署 Flask 项目
: https://lufficc.com/blog/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu
小接口我用的 tornado 做 flask 的 webserver
flask 启动的时候可以设置–progress 参数,可以设置允许的并发数
processes

