10-Flask 部署:使用 gunicorn 部署 flask 项目.md
- gunicron 官网:https://docs.gunicorn.org/en/stable/
- github 地址:https://github.com/benoitc/gunicorn
1、WSGI
1.1、WSGI 协议
Web 框架专注于业务逻辑、专注于HTML文档的生成。
Web 服务器用于处理和响应 HTTP 请求(HTTP 请求接收、建立连接、返回响应等)。
Web 框架和 Web 服务器之间的通信,需要一套双方都遵守的接口协议。这就是 WSGI 协议。
1.2、WSGI 容器
常用的 WSGI 容器有 Gunicorn 和 uWSGI,Gunicorn 直接用命令启动,不需要编写配置文件,相对 uWSGI 要容易很多。
2、并发模型
并发模型决定了服务器如何处理多个并发请求。主要的并发模型包括:
- 线程模型:每个请求由一个线程处理,线程之间共享内存。
- 进程模型:每个请求由一个独立的进程处理,进程之间不共享内存。
- 异步模型:通过事件循环处理多个请求,常见于高并发的IO密集型应用。
Gunicorn支持多种并发模型,使其能够在不同的应用场景下提供最佳性能。
3、gunicorn 介绍
gunicorn(绿色独角兽 Green Unicorn 的简称)是一个 Python WSGI http server,只支持在 Unix 系统上运行,来源于 Ruby 的 unicorn 项目。
gunicorn 广泛兼容各种 web 框架,实现简单,服务器资源少,而且速度相当快。官方建议 Nginx+gunicorn 性能最好。
gunicorn 使用 prefork master-worker 模型(在 gunicorn 中,master 被称为 arbiter),gunicorn在启动时,会在主进程中预先 fork 出指定数量的 worker 进程来处理请求,即一个 master 进程管理多个 worker 进程(管理进程:master,工作进程:worker),所有请求和响应均由 Worker 处理。
Master 进程是一个简单的loop, 监听 worker 不同进程信号并且作出响应。这样可以减少频繁创建和销毁进程的开销,但是一个进程相对占用资源,会消耗大量内存。
gunicorn 推荐的 worker 数量是:(2*$num_cores)+1
。
为啥要用 gunicorn
Flask 是一个 Platform,他本身并不包括 Web Server,为了使用方便,Flask 内置了一个 Werkzeug wsgi server 但是这个 server 并不高效。 如果是工业部署的话, 就需要用 Gunicorn 去替代掉这个内置的 Wsgi Server。提升服务处理能力,比如,使用 Gunicorn 部署多个 Flask 应用实例,提升服务并发处理能力;使用 Gunicorn + gevent worker,monkeypatch 掉 Python 原生网路库,进一步提升处理能力,遇到 IO 等待时,挂起当前请求,处理其它请求。
简单说下几种部署方式
- Flask 内置 WebServer + Flask App = 弱鸡版本的 Server, 单进程(单 worker) / 失败挂掉 / 不易 Scale
- Gunicorn + Flask App = 多进程(多 worker) / 多线程 / 失败自动帮你重启 Worker / 可简单Scale
- 多 Nginx + 多 Gunicorn + Flask App = 小型多实例 Web 应用,一般也会给 gunicorn 挂 supervisor
在生产环境中:一般都是请求的走向都是 Nginx->gunicorn->flask/django app
gunicorn 特点
- 兼容性强:支持多种 Web 框架,如 Django、Flask、Pyramid 等。
- 高性能:基于pre-fork worker模型,能充分利用多核CPU。
- 易于配置:提供了多种配置方式,包括命令行参数、配置文件和环境变量。
- 稳定性:在生产环境中广泛使用,经过了大量的实践检验。
- 简单易上手。
目前 gunicorn 只能运行在 Linux,不支持 windows。
4、gunicorn 安装
gunicorn 安装非常简单,使用命令 pip install gunicorn
即可。一般使用它,主要是为使用其异步的 worker 模型,还需要安装对应的异步模块。
1 |
|
5、gunicorn 使用
这里使用 gunicorn 部署一个 Flask 项目。
如下例子,保存为 app.py
1 |
|
在 shell 中输入你的启动配置,比如:
1 |
|
这样运行正常就可以启动服务器了。
如果要通过网络访问,则需要绑定不同的地址(也可以同时设置监听端口),设置 0.0.0.0 可以监听到所有 IP 的请求:
1 |
|
监控和调试
可以使用多种工具监控和调试Gunicorn的性能。例如,使用Prometheus和Grafana进行监控,或者使用New Relic进行应用性能管理。
6、绑定端口
linux 通常会禁止绑定使用 1024 以下的端口,除非在 root 用户权限。很多人在使用 gunicorn 时试图将其绑定到 80 或者 443 端口,发现无效。如果想绑定到这些端口,常见的有如下的几种方法:
- 使用 Nginx 代理转发。
- sudo 启动 gunicorn。
- 安装额外的程序。
7、结束 gunicorn 服务进程
使用 ps -ef | grep gunicorn
命令找出 gunicorn 所有进程。
1 |
|
然后使用 kill -9 进程ID
命令来杀掉进程,注意,我们找到主进程杀掉即可,子进程会随之结束,在上例中,主进程号为 23035.
1 |
|
杀掉进程后,稍等几秒,再使用 ps -ef | grep gunicorn
查看,发现 gunicorn 服务进程已全部杀掉。
8、配置文件
使用 gunicorn -h
可以看到 gunicorn 有非常多的配置项,因此通常会写成一个配置文件来进行配置。
比如 gunicorn.conf 文件
1 |
|
注意上面 log 项,如果需要将这些 log 文件统一放到 log 文件夹下,事先要先建好,不然运行时会报错。
运行代码为:
1 |
|
9、Gunicorn 工作原理
Gunicorn 使用 pre-fork worker 模型,这意味着在处理请求之前,它会预先 fork 出多个 worker 进程。每个 worker 进程都是独立的,可以在不同的 CPU 核心上运行。这种模型的优点在于:
- 隔离性好:每个 worker 进程都是独立的,如果一个进程崩溃,不会影响其他进程。
- 扩展性强:可以根据需要增加或减少worker进程的数量。
- 性能优越:可以充分利用多核CPU的并行处理能力。