从Django/Flask开发到上线:一份保姆级的uWSGI + Nginx生产环境配置清单

张开发
2026/4/21 18:42:22 15 分钟阅读

分享文章

从Django/Flask开发到上线:一份保姆级的uWSGI + Nginx生产环境配置清单
从Django/Flask开发到上线一份保姆级的uWSGI Nginx生产环境配置清单当你完成了一个Django或Flask应用的开发满怀期待地准备将其部署到生产环境时可能会遇到各种意想不到的问题。开发环境下运行良好的应用在生产环境中却频频崩溃这几乎是每个Python开发者都会经历的成人礼。本文将带你一步步完成从开发到上线的完整部署流程重点解决那些开发跑得好一上线就崩的典型问题。1. 生产环境基础准备在开始配置uWSGI和Nginx之前我们需要确保服务器环境已经准备就绪。与开发环境不同生产环境需要考虑安全性、稳定性和性能等多方面因素。首先创建一个专用的系统用户来运行你的应用是个好习惯。这可以避免使用root权限运行应用带来的安全风险sudo adduser --system --group --no-create-home myappuser接下来是Python环境的隔离。即使服务器上只运行一个Python应用使用虚拟环境也是必要的python -m venv /opt/myapp/venv source /opt/myapp/venv/bin/activate pip install -r requirements.txt生产环境中常见的目录结构建议如下/opt/myapp/ ├── venv/ # 虚拟环境 ├── src/ # 项目代码 │ ├── manage.py │ ├── myapp/ │ └── ... ├── logs/ # 日志文件 ├── static/ # 静态文件 └── media/ # 用户上传文件提示确保你的应用代码、虚拟环境和数据文件都有正确的权限设置。通常应用用户只需要对特定目录有读写权限。2. uWSGI深度配置指南uWSGI作为应用服务器其配置直接影响着应用的性能和稳定性。下面是一个经过生产环境验证的uWSGI配置文件模板uwsgi.ini我们将逐项解析关键配置[uwsgi] # 基础配置 project myapp uid myappuser gid myappuser base /opt/myapp chdir %(base)/src module %(project).wsgi:application home %(base)/venv # 进程管理 master true processes 4 threads 2 max-requests 1000 harakiri 30 harakiri-verbose true reload-mercy 10 # 性能优化 buffer-size 65536 post-buffering 65536 max-worker-lifetime 3600 worker-reload-mercy 60 # 日志记录 logto %(base)/logs/uwsgi.log log-format %(addr) - %(user) [%(ltime)] %(method) %(uri) %(proto) %(status) %(size) %(referer) %(uagent) disable-logging false # 通信设置 socket /run/uwsgi/%(project).sock chown-socket %(uid):www-data chmod-socket 660 vacuum true # 高级选项 lazy-apps true thunder-lock true enable-threads true关键配置项解析进程与线程processes和threads的设置需要根据服务器CPU核心数和应用特性调整。通常建议CPU密集型应用进程数CPU核心数线程数1I/O密集型应用进程数CPU核心数线程数2-4资源限制max-requests每个工作进程处理的最大请求数预防内存泄漏harakiri请求超时时间(秒)防止长时间运行的请求阻塞系统通信协议选择Unix socket推荐当Nginx和uWSGI在同一服务器时性能最佳TCP socket适用于分布式部署HTTP兼容性最好但性能较差注意修改配置后使用uwsgi --reload /tmp/myapp-master.pid平滑重启而不是直接杀死进程。3. Nginx与uWSGI的完美配合Nginx作为前端服务器负责处理静态文件、SSL终止和负载均衡等任务。以下是与uWSGI配合的最佳实践配置upstream myapp { server unix:/run/uwsgi/myapp.sock; } server { listen 80; server_name example.com; # 静态文件处理 location /static/ { alias /opt/myapp/static/; expires 30d; access_log off; } location /media/ { alias /opt/myapp/media/; expires 30d; access_log off; } # 动态请求转发 location / { include uwsgi_params; uwsgi_pass myapp; # 超时设置 uwsgi_read_timeout 300; uwsgi_send_timeout 300; uwsgi_connect_timeout 75; # 缓冲区优化 uwsgi_buffer_size 64k; uwsgi_buffers 4 64k; uwsgi_busy_buffers_size 128k; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 日志配置 access_log /var/log/nginx/myapp.access.log; error_log /var/log/nginx/myapp.error.log; }常见问题解决方案502 Bad Gateway错误检查socket文件权限www-data用户需要可读写确认uWSGI进程正在运行查看Nginx和uWSGI日志获取具体错误信息静态文件无法加载确保Nginx配置中的alias路径正确运行python manage.py collectstatic收集静态文件检查静态文件目录权限性能瓶颈调整uWSGI的processes和threads参数考虑添加缓存头Cache-Control优化静态文件对于高并发场景可以增加Nginx的worker_processes4. 部署后的监控与优化部署完成后持续的监控和优化是保证应用稳定运行的关键。以下是一些实用的监控方法基础监控命令# 查看uWSGI进程状态 ps aux | grep uwsgi # 实时监控Nginx访问日志 tail -f /var/log/nginx/myapp.access.log # 检查系统资源使用情况 htop性能指标监控表指标正常范围监控方法异常处理CPU使用率70%top,htop优化代码增加服务器内存使用80%free -m检查内存泄漏增加内存磁盘I/Oawait10msiostat -x 1使用SSD优化磁盘操作网络流量根据带宽iftop优化静态资源启用CDN请求响应时间500msNginx日志优化数据库查询缓存日志分析技巧使用grep过滤特定错误grep 500 Internal Server Error /var/log/nginx/myapp.access.log统计最常见请求awk {print $7} /var/log/nginx/myapp.access.log | sort | uniq -c | sort -nr | head -20分析响应时间分布awk {print $NF} /var/log/nginx/myapp.access.log | sort -n | uniq -c自动化部署建议对于频繁更新的应用可以考虑以下自动化方案使用Fabric或Ansible编写部署脚本配置Git钩子在代码推送后自动部署设置CI/CD流水线进行自动化测试和部署# 示例Fabric部署脚本片段 from fabric import task task def deploy(c): with c.cd(/opt/myapp/src): c.run(git pull origin master) c.run(../venv/bin/pip install -r requirements.txt) c.run(../venv/bin/python manage.py migrate) c.run(../venv/bin/python manage.py collectstatic --noinput) c.run(sudo systemctl restart uwsgi)5. 高级场景与故障排除当你的应用规模增长或遇到特殊需求时可能需要考虑以下高级配置多应用部署在同一服务器上部署多个Django/Flask应用时建议为每个应用创建独立的uWSGI配置文件使用不同的socket文件或端口号在Nginx中配置多个server块或location规则# 多应用Nginx配置示例 upstream app1 { server unix:/run/uwsgi/app1.sock; } upstream app2 { server unix:/run/uwsgi/app2.sock; } server { listen 80; server_name app1.example.com; location / { include uwsgi_params; uwsgi_pass app1; } } server { listen 80; server_name app2.example.com; location / { include uwsgi_params; uwsgi_pass app2; } }SSL/TLS配置使用Lets Encrypt免费证书为你的应用启用HTTPSsudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d example.com -d www.example.comNginx的SSL配置优化ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers off; add_header Strict-Transport-Security max-age63072000 always;常见故障排除应用随机崩溃检查uWSGI日志中的harakiri超时记录增加harakiri超时时间或优化慢请求检查max-requests设置是否过低内存持续增长降低max-requests值使进程更频繁重启使用memory-reporttrue监控内存使用检查应用代码中的内存泄漏高并发时性能下降增加uWSGI的processes和threads调整Nginx的worker_connections考虑添加Redis缓存层# 监控uWSGI内存使用 watch -n 1 ps aux | grep uwsgi | grep -v grep | awk {print \$4,\$5,\$6,\$11}性能优化技巧启用uWSGI的缓存功能cache2 namemycache,items1000,blocksize4096使用uWSGI的异步模式处理长轮询请求async 100 ugreen true对于I/O密集型应用考虑使用geventgevent 100在实际项目中我发现最容易被忽视的是日志轮转配置。没有适当的日志管理日志文件可能会迅速耗尽磁盘空间。为uWSGI和Nginx配置logrotate是个好习惯# /etc/logrotate.d/myapp /var/log/nginx/*.log /opt/myapp/logs/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 www-data adm sharedscripts postrotate [ -f /var/run/nginx.pid ] kill -USR1 cat /var/run/nginx.pid [ -f /tmp/myapp-master.pid ] kill -HUP cat /tmp/myapp-master.pid endscript }

更多文章