Python中如何解决简单Flask API服务器程序阻塞的问题?多端口多实例、wsgi,还是Flask程序自身能解决?

Python 里用 Flask 写的 API 服务器端,程序就是对收到的用户名密码连接到本地 MySQL 查询一下是否正确然后返回授权信息。虽然正常情况下能很快处理一个请求,但是测试了下发现 Flask 的 API 函数是阻塞执行的。。在处理一个请求时其它的请求竟然就那么停着。。
搜了下资料,是不是要加什么 uwsgi 的,或者是那个 return jsonify() 函数可以做什么文章,异步返回吗?或者是在多个 Tcp 端口上开启多个 flask 实例,然后 Nginx 反向代理。。
小白求教。。
Python中如何解决简单Flask API服务器程序阻塞的问题?多端口多实例、wsgi,还是Flask程序自身能解决?


9 回复

flask 默认的 web server 是单线程的?这个还不是很清楚,不过默认的 web server 一般不推荐生产环境使用吧。具体用哪个 web server 我也不是很明白,楼下推荐一下。至于要不要 Nginx 来做个集群负载就看需要了。。


简单来说,Flask自带的开发服务器是单线程的,处理请求时会阻塞。生产环境不能用它。核心解决方案是搭配一个WSGI应用服务器,比如Gunicorn或uWSGI。

Flask本身只是个Web框架,不是全功能的服务器。开发服务器(app.run())性能很差,只能用于调试。要解决阻塞,你需要一个能处理并发请求的WSGI服务器。这些服务器会管理一个工作者进程/线程池,一个请求阻塞时,其他工作者可以继续处理新请求。

最直接的方法:用Gunicorn 假设你的主程序文件叫 app.py,里面创建了Flask应用实例 app

  1. 安装Gunicorn:

    pip install gunicorn
    
  2. 用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

回到顶部