文章内容
2025/12/11 18:07:06,作 者: 黄兵
uWSGI 配置示例
在 Ubuntu VPS 上,如果 uWSGI 配置不合理,大量的请求会导致内存飙升,就像这样:

这个是最开始的配置:
[uwsgi] strict = true module = manage:app master = true enable-threads = true vacuum = true ; Delete sockets during shutdown single-interpreter = true die-on-term = true ; Shutdown when receiving SIGTERM (default is respawn) need-app = true disable-logging = true ; Disable built-in logging log-4xx = true ; but log 4xx's anyway log-5xx = true ; and 5xx's harakiri = 60 ; forcefully kill workers after 60 seconds buffer-size = 65535 ; Reset the default buffer size max-requests = 1000 ; Restart workers after this many requests max-worker-lifetime = 3600 ; Restart workers after this many seconds reload-on-rss = 1024 ; Restart workers after this much resident memory worker-reload-mercy = 60 ; How long to wait before forcefully killing workers cheaper-algo = busyness processes = 32 ; Maximum number of workers allowed cheaper = 8 ; Minimum number of workers allowed cheaper-initial = 16 ; Workers created at startup cheaper-overload = 1 ; Length of a cycle in seconds cheaper-step = 16 ; How many workers to spawn at a time cheaper-busyness-multiplier = 30 ; How many cycles to wait before killing workers cheaper-busyness-min = 20 ; Below this threshold, kill workers (if stable for multiplier cycles) cheaper-busyness-max = 70 ; Above this threshold, spawn new workers cheaper-busyness-backlog-alert = 16 ; Spawn emergency workers if more than this many requests are waiting in the queue cheaper-busyness-backlog-step = 2 ; How many emergency workers to create if there are too many requests in the queue socket = [::]:5002 chmod-socket = 660
对于 2核 4G 内存 的配置,最大的问题在于:processes = 32 和 cheaper-step = 16。
在 2 核 CPU 上开 32 个进程会导致严重的上下文切换(Context Switching),CPU 效率反而下降。更严重的是,当流量来临时,cheaper-step = 16 会瞬间创建 16 个进程,假设每个 Python 进程占用 60MB-100MB 内存,这会瞬间吃掉 1GB-1.6GB 内存,导致内存监控出现“尖峰”。
下面是调整后的配置:
[uwsgi] # --- 基础配置 --- strict = true module = manage:app master = true enable-threads = true ; 启用线程支持(虽然主要靠进程抗压,但某些第三方库如 Sentry 需要线程) vacuum = true ; 退出时清理 socket 文件 single-interpreter = true ; 单解释器模式,节省内存 die-on-term = true ; 接收 SIGTERM 信号时完全退出而非重启 need-app = true ; 如果加载 app 失败,则不启动 uWSGI # --- 日志配置 --- disable-logging = true ; 禁用常规请求日志(仅记录错误),极大提升性能 log-4xx = true ; 但记录 4xx 错误 log-5xx = true ; 和 5xx 错误 # --- 超时与缓冲 --- harakiri = 60 ; 请求超时强制杀掉(秒),防止卡死 buffer-size = 65535 ; 增加 header 缓冲区大小,防止 url 过长报错 # --- 进程回收机制 (防止内存泄漏) --- max-requests = 2000 ; 处理 2000 个请求后重启 worker(防内存缓慢泄漏) max-requests-delta = 100 ; 增加随机性,防止所有 worker 同时重启导致服务抖动 max-worker-lifetime = 3600 ; worker 最长存活 1 小时 reload-on-rss = 300 ; 【关键】单个 worker 内存达到 300MB 时强制重启(原 1024 太大了,4G 内存扛不住几个) worker-reload-mercy = 10 ; 重启前等待 worker 处理完当前请求的最长时间(秒) # --- 动态进程管理 (核心优化) --- # 2核 4G 建议最大进程数 4-8 个。32 个太多了,会导致 CPU 频繁切换上下文。 cheaper-algo = busyness processes = 8 ; 【修改】最大进程数:8 (足够跑满 2 核 CPU,且内存安全) cheaper = 2 ; 【修改】最小保留空闲进程数 cheaper-initial = 4 ; 【修改】启动时创建的进程数 cheaper-overload = 5 ; 【修改】持续繁忙 5 秒才增加进程(防止过于敏感) cheaper-step = 1 ; 【关键修改】每次只增加 1 个进程!(原 16 会导致内存瞬间爆炸) # --- 扩缩容算法参数 --- cheaper-busyness-multiplier = 30 ; 计算繁忙度的周期数 cheaper-busyness-min = 20 ; 繁忙度低于 20% 杀掉 worker cheaper-busyness-max = 70 ; 繁忙度高于 70% 增加 worker cheaper-busyness-backlog-alert = 16 ; 队列积压超过 16 个请求时应急 cheaper-busyness-backlog-step = 1 ; 【修改】应急时也只增加 1 个进程 # --- 网络绑定 --- socket = [::]:5002 chmod-socket = 660
🔧 主要修改点解读:
processes = 32->8:原因:2 核 CPU 跑 32 个 Python 进程不仅不会变快,反而因为 CPU 要在 32 个进程间来回切换(Context Switching),导致性能下降。8 个进程足以处理高并发 I/O(上传),同时保证内存不会被撑爆。
cheaper-step = 16->1:原因:这是您之前“内存瞬间飙升”的罪魁祸首。之前一旦忙碌,瞬间启动 16 个进程,内存瞬间增加 ~1GB。改为
1后,它会根据负载平滑地一个一个增加,曲线会很平稳。
reload-on-rss = 1024->300:原因:您的总内存只有 4096MB。如果允许一个进程跑到 1024MB,那么 4 个进程就把服务器吃光了。限制在 300MB 可以确保 8 个进程全开时(8 * 300 = 2400MB),系统还有 1.5GB 留给操作系统和其他缓存。
post-buffering = 8192(新增):原因:这对文件上传非常有用。它会把 HTTP Body 读入内存缓冲区(如果超过大小则存入磁盘临时文件),然后再传给 Flask。这能解耦上传速度和应用处理速度,让 uWSGI Worker 更快释放出来处理下一个请求。
其它相关推荐:
1、uWsgi invalid request block size: 21573 (max 4096)...skip
2、使用 uWSGI、nginx、systemd 部署 Django
3、invalid request block size: 6774 (max 4096)...skip
4、uWSGI + nginx + systemd 配置示例
5、uWSGI running as root, you can use --uid/--gid/--chroot options
评论列表