Nginx与uWSGI部署Python应用完整指南

Dylan
Dylan
发布时间:2026-10-13 | 2人浏览过
原创

本文详细介绍如何利用Nginx与uWSGI搭建高性能Python应用服务器。内容涵盖uWSGI安装、基础WSGI应用编写、多进程多线程配置、配置文件优化,以及Nginx反向代理设置。此外,还深入讲解了Flask应用集成、虚拟环境隔离、多应用路由挂载及Socket文件权限处理等关键部署技巧,帮助开发者实现稳定高效的Web服务发布。

uWSGI是一款功能丰富的Web应用服务器,集应用托管、反向代理、进程管理及性能监控于一体。它既支持标准的WSGI协议,也兼容高性能且低内存占用的uWSGI自有协议(据称内存占用约为mod_wsgi的一半,虽未实测但口碑良好)。尽管uWSGI具备独立作为Web服务器的能力,但最佳实践是将其与Nginx配合使用:uWSGI专注处理应用逻辑,Nginx负责前端静态资源与高并发请求,二者结合能最大化发挥各自优势。本文将逐步演示如何构建基于uWSGI与Nginx的Python应用运行环境。

安装uWSGI

pip install uwsgi

首先,我们需要创建一个基础的WSGI应用示例,并将其保存为“server.py”文件。

def application(environ, start_response):
  status = '200 OK'
  output = 'Hello World!'
 
  response_headers = [('Content-type', 'text/plain'),
            ('Content-Length', str(len(output)))]
  start_response(status, response_headers)
 
  return [output]

接下来,在uWSGI环境中运行该应用,具体执行命令如下:

uwsgi --http :9090 --wsgi-file server.py

执行上述命令后,在浏览器中访问“http://localhost:9090”,即可看到页面显示“Hello World!”。

上述命令中,“--http”参数用于指定HTTP监听的地址与端口,“--wsgi-file”则指向WSGI应用的入口文件。uWSGI会自动查找名为“application”的对象并调用它,这是WSGI标准的默认约定。

进一步地,uWSGI支持通过多进程和多线程模式启动应用,并具备状态监控功能。我们将启动命令调整为:

复制代码 代码如下:

$ uwsgi --http :9090 --wsgi-file server.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

执行该命令后,uWSGI将启动一个主进程(Master)以及4个应用工作进程,每个工作进程包含2个线程。主进程负责监控其他进程状态,若发现进程异常退出则自动重启。此外,访问“127.0.0.1:9191”可获取JSON格式的应用运行状态信息。uWSGI还提供了一个名为“uwsgitop”的监控工具,界面类似Linux的top命令,可通过pip安装使用。

当启动参数过多时,建议将配置写入文件,启动时指定配置文件即可。配置文件支持键值对、XML或YAML格式,本文采用简洁的键值对格式。请创建一个名为“myapp.ini”的配置文件:

[uwsgi]
http=:9090
wsgi-file=server.py
master=true
processes=4
threads=2
stats=127.0.0.1:9191

随后,启动命令可简化为:

$ uwsgi myapp.ini

配置Nginx

Nginx的安装可参考相关文档,本文以Ubuntu Linux为例,其他系统如MacOS的操作流程基本一致。

首先,需将uWSGI的监听方式从HTTP改为Socket监听。具体操作是删除配置文件中的“http”项,替换为“socket”项:

[uwsgi]
socket=127.0.0.1:3031
wsgi-file=server.py
master=true
processes=4
threads=2
stats=127.0.0.1:9191

接着,编辑Nginx的配置文件。在Ubuntu系统中,默认路径为“/etc/nginx/sites-enabled/default”。将根路径部分的配置修改为:

location / {
  include uwsgi_params;
  uwsgi_pass 127.0.0.1:3031;
}

该配置表明Nginx将接收到的所有请求转发至“127.0.0.1:3031”端口,即uWSGI服务器。完成配置后,重启Nginx服务并启动uWSGI服务器:

$ sudo service nginx restart
$ uwsgi myapp.ini

此时访问“http://localhost”,页面将再次显示“Hello World!”,证明部署成功。

运行Flask应用

集成Flask应用非常简单,只需将“server.py”的内容替换为Flask代码即可。当然,前提是先安装Flask库:

from flask import Flask
application = Flask(__name__)
 
@application.route('/')
def index():
  return '<h1>Hello World</h1>'

许多开发者习惯将Flask应用对象命名为“app”,但这与WSGI标准要求的“application”不符。uWSGI提供了“callable”配置项来解决此问题,只需在配置文件中添加该项即可指定自定义的应用对象名:

[uwsgi]
...
callable=app

通过上述配置,我们的Flask应用现在可以使用“app”作为入口对象名了。

from flask import Flask
app = Flask(__name__)
 
@app.route('/')
def index():
  return '<h1>Hello World</h1>'

使用Python虚拟环境

为避免不同应用间的依赖冲突,强烈建议使用Python虚拟环境。uWSGI对此支持良好,只需在配置文件中添加“virtualenv”项指定虚拟环境路径:

[uwsgi]
...
virtualenv=/home/bjhee/virtualenv

部署多个应用

Nginx可同时运行多个应用,不限于Python。若希望通过不同URL路径路由到不同应用,直接修改根目录配置已不适用。假设希望访问“http://localhost/myapp”来使用我们的应用,首先需在Nginx配置中加入以下内容:

location /myapp {
  include uwsgi_params;
  uwsgi_param SCRIPT_NAME /myapp;
  uwsgi_pass 127.0.0.1:3031;
}

此处定义了uWSGI参数“SCRIPT_NAME”,其值为应用路径“/myapp”。随后,在uWSGI启动配置中,移除“wsgi-file”项,并添加:

[uwsgi]
...
mount=/myapp=server.py
manage-script-name=true

“mount”参数用于将“/myapp”路径路由至“server.py”文件,“manage-script-name”参数则启用Nginx中配置的“SCRIPT_NAME”。再次重启Nginx和uWSGI后,即可通过“http://localhost/myapp”访问应用。

补充内容

前述示例均通过“127.0.0.1:3031”Socket端口连接Nginx与uWSGI。实际上,使用Socket文件方式更为灵活,无需硬编码端口。在uWSGI启动配置中,修改“socket”项为:

[uwsgi]
socket=/tmp/uwsgi.sock
...

启动uWSGI后,系统会自动创建“/tmp/uwsgi.sock”文件。接着修改Nginx配置文件,将“uwsgi_pass”指向该Socket文件:

location /myapp {
  include uwsgi_params;
  uwsgi_param SCRIPT_NAME /myapp;
  uwsgi_pass unix:/tmp/uwsgi.sock;
}

重启Nginx即可生效。在此过程中,我曾遇到权限问题:Nginx默认运行用户为“www-data:adm”,而uWSGI由其他用户创建Socket文件,导致Nginx无读写权限。解决方法是手动修改Socket文件权限(chmod)。若遇到类似情况,请检查并确保Nginx用户对该文件拥有读写权限。

此外,关于“.egg”包的解压缩临时目录,在uWSGI应用中同样适用。Linux系统默认路径为用户主目录下的“.python-eggs”,例如“/home/bjhee/.python-eggs”。可通过设置环境变量“PYTHON_EGG_CACHE”来更改此路径。

以上就是本文的全部内容,希望能为您的Python应用部署提供有益参考,欢迎支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表