flask生产环境必须用gunicorn+wsgi+nginx反向代理;gunicorn应绑定127.0.0.1或unix socket而非0.0.0.0;nginx需配置proxy_set_header透传真实ip;worker数依io特性调整,必加--preload和合理timeout;systemd服务需设type=simple、restart=always及正确用户权限。

Flask 不能直接暴露在公网,flask run 只能用于开发调试;生产环境必须用 Gunicorn 做 WSGI 容器,再由 Nginx 反向代理——这不是可选项,是避免服务一压就挂的底线配置。
为什么 Gunicorn 启动后 curl 不通?常见绑定地址错误
最常踩的坑是直接写 gunicorn app:app -b 0.0.0.0:8000,然后发现本地能通、Nginx 却连不上。原因在于:Nginx 和 Gunicorn 通常应走 Unix socket 或 127.0.0.1,而非监听全网卡。
- 用
127.0.0.1:8000更安全:避免端口意外暴露,也符合 Nginx 默认proxy_pass http://127.0.0.1:8000的预期 - 更推荐 Unix socket:
--bind unix:/tmp/myapp.sock,性能略高、权限可控,但需确保 Nginx 进程(通常是www-data)有读写权限 - 别用
--reload上生产:它依赖文件系统 inotify,会干扰日志轮转和 systemd 管理,且可能引发 worker 内存泄漏 - 启动后用
ss -tlnp | grep :8000或ls -l /tmp/myapp.sock确认监听状态,而不是只看终端有没有报错
如何让 Nginx 正确转发请求并透传真实 IP
如果 Flask 日志里全是 127.0.0.1,或者用户登录态异常,大概率是 Nginx 没配好代理头。它不是“转发过去就行”,而是要主动告诉后端谁真正发来了请求。
- 必须加这三行到
location /块里:proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
X-Forwarded-For是逗号分隔列表,$proxy_add_x_forwarded_for会自动追加当前 client IP,比硬写$remote_addr更可靠 - 若用了 CDN 或多层代理,还需配
X-Forwarded-Proto和X-Forwarded-Port,否则url_for(_external=True)生成的链接可能是 http 而非 https - 检查 Nginx 配置语法:
sudo nginx -t,重载:sudo systemctl reload nginx
Gunicorn 参数怎么设才不翻车?别盲目堆 workers
worker 数量不是越多越好,设错反而导致上下文切换开销暴涨、内存耗尽。关键得看你的应用 IO 特性,而不是 CPU 核数本身。
- 同步阻塞型(比如频繁查 MySQL、调外部 HTTP):从
--workers 4起步,观察htop中 CPU 利用率和等待时间(%wa),再微调 - 默认
--worker-class sync就够用;除非你明确用了async/await且验证过gevent兼容性,否则别碰异步 worker - 必加
--preload:让 master 进程提前加载代码,避免每个 worker 重复 import,省内存、启得快 -
--timeout 30是安全线,但若业务真有导出报表等长任务,应在路由层单独处理超时(如用 Celery),而不是全局拉高 timeout - 日志别打屏:
--access-logfile /var/log/myapp/gunicorn_access.log --error-logfile /var/log/myapp/gunicorn_error.log,配合 logrotate
systemd 服务文件里哪些字段最容易漏?
裸跑 gunicorn 没有意义——断 SSH、服务器重启、worker 崩溃,服务就没了。systemd 是现代 Linux 的标准守护方案,但配置不对等于没守。
-
Type=simple:Gunicorn 默认不 daemonize,必须设为 simple,否则 systemd 会误判进程已退出 -
Restart=always+RestartSec=5:保证崩溃后秒级恢复 -
StartLimitIntervalSec=60和StartLimitBurst=3:防雪崩——1 分钟内连续失败 3 次就暂停拉起,留时间人工介入 -
Environment="PATH=/path/to/venv/bin"和WorkingDirectory必须显式指定,否则找不到包或配置文件 - 权限别乱设
User=root:用User=www-data或专用低权用户,socket 文件路径也得匹配该用户 uid
最常被忽略的是 Gunicorn 和 Nginx 的超时协同:Nginx 的 proxy_read_timeout 必须 ≥ Gunicorn 的 --timeout,否则 Nginx 会在 worker 处理完前主动断连,返回 504。这个细节不查日志根本看不出问题。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











