文章内容

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 = 32cheaper-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

🔧 主要修改点解读:

  1. processes = 32 -> 8:

    • 原因:2 核 CPU 跑 32 个 Python 进程不仅不会变快,反而因为 CPU 要在 32 个进程间来回切换(Context Switching),导致性能下降。8 个进程足以处理高并发 I/O(上传),同时保证内存不会被撑爆。

  2. cheaper-step = 16 -> 1:

    • 原因:这是您之前“内存瞬间飙升”的罪魁祸首。之前一旦忙碌,瞬间启动 16 个进程,内存瞬间增加 ~1GB。改为 1 后,它会根据负载平滑地一个一个增加,曲线会很平稳。

  3. reload-on-rss = 1024 -> 300:

    • 原因:您的总内存只有 4096MB。如果允许一个进程跑到 1024MB,那么 4 个进程就把服务器吃光了。限制在 300MB 可以确保 8 个进程全开时(8 * 300 = 2400MB),系统还有 1.5GB 留给操作系统和其他缓存。

  4. 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

Git Commit 规范
没有了
分享到:

发表评论

评论列表