uWSGI¶
uWSGI 是一个快速、编译后的服务器套件,具有超越基本服务器的广泛配置和功能。
由于是编译程序,性能非常出色。
超出基础应用的配置较为复杂,选项众多,初学者可能难以理解。
不支持 Windows(但可运行在 WSL 上)。
某些情况下安装需要编译器。
本页介绍了运行 uWSGI 的基础方法。请务必阅读其官方文档以了解更多功能。
安装¶
uWSGI 有多种安装方式。最简单的方法是安装 pyuwsgi 包,它为常见平台提供了预编译的安装包(wheel)。 但 pyuwsgi 不包含 SSL 支持,此功能可以通过反向代理来实现。
创建一个虚拟环境,安装你的应用,然后安装 pyuwsgi。
$ cd hello-app
$ python -m venv .venv
$ . .venv/bin/activate
$ pip install . # install your application
$ pip install pyuwsgi
如果你有可用的编译器,可以改为安装 uwsgi 包,或从源代码(sdist)安装 pyuwsgi。这两种方法都包含 SSL 支持。
$ pip install uwsgi
# or
$ pip install --no-binary pyuwsgi pyuwsgi
运行¶
运行 uWSGI 最基础的方式是启动一个 HTTP 服务器并导入你的应用。
$ uwsgi --http 127.0.0.1:8000 --master -p 4 -w hello:app
*** Starting uWSGI 2.0.20 (64bit) on [x] ***
*** Operational MODE: preforking ***
mounting hello:app on /
spawned uWSGI master process (pid: x)
spawned uWSGI worker 1 (pid: x, cores: 1)
spawned uWSGI worker 2 (pid: x, cores: 1)
spawned uWSGI worker 3 (pid: x, cores: 1)
spawned uWSGI worker 4 (pid: x, cores: 1)
spawned uWSGI http 1 (pid: x)
如果你使用的是应用工厂模式(app factory pattern),你需要创建一个 Python 文件用于创建应用,然后将 uWSGI 指向这个文件。
wsgi.py¶from hello import create_app
app = create_app()
$ uwsgi --http 127.0.0.1:8000 --master -p 4 -w wsgi:app
--http 选项会在本地机 127.0.0.1 的 8000 端口启动一个 HTTP 服务器。 --master 选项指定使用标准的 worker 管理器。-p 选项设置启动 4 个 worker 进程(可从 CPU * 2 开始估算)。-w 选项告诉 uWSGI 如何导入你的应用
外部绑定¶
不应以 root 身份运行本文档展示的配置,因为这会导致你的应用代码以 root 权限运行,存在安全风险。不过,这样就无法绑定到 80 或 443 等特权端口。推荐在 uWSGI 前使用反向代理,如 nginx 或 Apache httpd。虽然可以安全地以 root 身份运行 uWSGI,但该配置超出了本文档的范围。
相比使用标准 HTTP 代理,uWSGI 与 Nginx uWSGI 和 Apache mod_proxy_uwsgi 等服务器具有优化后的集成方式。 这些配置同样不在本页讨论范围内,请参考上述链接了解更多信息。
你可以使用 --http 0.0.0.0:8000 选项绑定到所有外部 IP 的非特权端口。 但在使用反向代理的情况下请勿这样做,否则可能会绕过代理访问应用。
$ uwsgi --http 0.0.0.0:8000 --master -p 4 -w wsgi:app
注意:0.0.0.0 不是一个可以在浏览器中访问的有效地址,浏览器中应使用具体的 IP 地址。
使用 gevent 实现异步¶
默认的同步(sync)worker 已适用于许多使用场景。如果你需要异步支持,uWSGI 提供了一个 gevent worker。 需要注意的是,这与 Python 的 async/await 或 ASGI 服务器规范不同。你必须在自己的代码中实际使用 gevent,才能从该 worker 中获得性能收益。
使用 gevent 时,要求 greenlet 版本不低于 1.0,否则类似 request 这样的上下文局部变量将无法正常工作。使用 PyPy 时,要求 PyPy 版本不低于 7.3.7。
$ uwsgi --http 127.0.0.1:8000 --master --gevent 100 -w wsgi:app
*** Starting uWSGI 2.0.20 (64bit) on [x] ***
*** Operational MODE: async ***
mounting hello:app on /
spawned uWSGI master process (pid: x)
spawned uWSGI worker 1 (pid: x, cores: 100)
spawned uWSGI http 1 (pid: x)
*** running gevent loop engine [addr:x] ***