Gunicorn

Gunicorn 是一个纯 Python WSGI 服务器,具有简单的配置和多个工作进程实现,用于性能调优。

  • 它倾向于轻松地与托管平台集成。

  • 它不支持 Windows(但在 WSL 上运行)。

  • 它易于安装,因为它不需要其他依赖项或编译。

  • 它使用 gevent 或 eventlet 内置了异步工作进程支持。

此页面概述了运行 Gunicorn 的基础知识。务必阅读其文档并使用 gunicorn --help 来了解有哪些可用功能。

安装

Gunicorn 易于安装,因为它不需要外部依赖项或编译。它仅在 WSL 下运行于 Windows。

创建一个虚拟环境,安装你的应用程序,然后安装 gunicorn

$ cd hello-app
$ python -m venv .venv
$ . .venv/bin/activate
$ pip install .  # install your application
$ pip install gunicorn

运行

Gunicorn 唯一的必需参数告诉它如何加载你的 Flask 应用程序。语法是 {module_import}:{app_variable}module_import 是包含你的应用程序的模块的点号分隔导入名称。 app_variable 是包含应用程序的变量。如果你正在使用应用程序工厂模式,它也可以是一个函数调用(带任何参数)。

# equivalent to 'from hello import app'
$ gunicorn -w 4 'hello:app'

# equivalent to 'from hello import create_app; create_app()'
$ gunicorn -w 4 'hello:create_app()'

Starting gunicorn 20.1.0
Listening at: http://127.0.0.1:8000 (x)
Using worker: sync
Booting worker with pid: x
Booting worker with pid: x
Booting worker with pid: x
Booting worker with pid: x

-w 选项指定要运行的进程数;起始值可以是 CPU * 2。默认值仅为 1 个工作进程,这可能不是你想要的默认工作进程类型。

默认情况下不会显示每个请求的日志,只会显示工作进程信息和错误。要显示 stdout 上的访问日志,请使用 --access-logfile=- 选项。

外部绑定

Gunicorn 不应以 root 身份运行,因为它会导致你的应用程序代码以 root 身份运行,这是不安全的。但是,这意味着无法绑定到端口 80 或 443。相反,应在 Gunicorn 前面使用反向代理,例如 nginxApache httpd

你可以使用 -b 0.0.0.0 选项绑定到非特权端口上的所有外部 IP。在使用反向代理设置时不要这样做,否则将有可能绕过代理。

$ gunicorn -w 4 -b 0.0.0.0 'hello:create_app()'
Listening at: http://0.0.0.0:8000 (x)

0.0.0.0 不是一个有效的导航地址,你将在浏览器中使用一个特定的 IP 地址。

使用 gevent 或 eventlet 进行异步

默认同步工作进程适用于许多用例。如果您需要异步支持,Gunicorn 提供使用 geventeventlet 的工作进程。这与 Python 的 async/await 或 ASGI 服务器规范不同。您必须在自己的代码中实际使用 gevent/eventlet,才能看到使用工作进程的任何好处。

在使用 gevent 或 eventlet 时,需要 greenlet>=1.0,否则上下文局部变量(例如 request)将无法按预期工作。在使用 PyPy 时,需要 PyPy>=7.3.7。

要使用 gevent

$ gunicorn -k gevent 'hello:create_app()'
Starting gunicorn 20.1.0
Listening at: http://127.0.0.1:8000 (x)
Using worker: gevent
Booting worker with pid: x

要使用 eventlet

$ gunicorn -k eventlet 'hello:create_app()'
Starting gunicorn 20.1.0
Listening at: http://127.0.0.1:8000 (x)
Using worker: eventlet
Booting worker with pid: x