Nginx虚拟主机无法实现进程级内存隔离,必须通过systemd+cgroup v2对整个服务设MemoryMax=512M等全局限制,并配合client_max_body_size等配置降低内存压力,确保master与workers统一纳入同一cgroup。

Nginx 虚拟主机本身不直接控制进程级内存隔离——它只是按 server 块分发请求,所有虚拟主机共享同一组 worker 进程。真正的内存隔离必须在系统服务层实现,即通过 systemd + cgroup v2 对整个 Nginx 服务施加统一的内存上限,并确保其子进程(包括 master 和所有 workers)都被纳入同一受控 cgroup。
要让多个虚拟主机“感觉”彼此内存隔离,核心不是给每个 server 单独限内存,而是防止任一虚拟主机因配置不当(如大文件上传、慢日志、未限制的 proxy 缓存)拖垮整台服务器。以下是关键做法:
用 systemd 设置全局内存上限
- 运行
sudo systemctl edit nginx,创建覆盖配置 - 在
[Service]段中加入:-
MemoryMax=512M:硬性限制 Nginx 整体最大内存使用(超限时内核 OOM killer 会介入) -
MemoryAccounting=yes:启用内存用量统计(cgroup v2 必需) -
Delegate=yes:允许 Nginx 自己在子 cgroup 中管理 worker 进程(便于后续细粒度观察)
-
- 执行
sudo systemctl daemon-reload && sudo systemctl restart nginx生效
验证是否真正生效
- 查看 cgroup 内存上限:
cat /sys/fs/cgroup/system.slice/nginx.service/memory.max
应显示536870912(即 512MB 的字节数) - 查看当前内存使用:
systemctl status nginx | grep Memory - 检查 worker 进程是否被纳入:
cat /proc/$(pgrep nginx | head -n1)/cgroup | grep nginx.service
配合 Nginx 配置降低内存压力
- 在
http或各server块中设置:-
client_max_body_size 20M;—— 防止单个上传耗尽内存 -
client_header_timeout 10; client_body_timeout 10;—— 快速切断慢连接 -
reset_timed_out_connection on;—— 主动释放卡住的连接 -
proxy_buffering off;(若后端稳定)或合理调小proxy_buffers—— 减少缓冲区开销
-
不推荐但需避开的误区
- 不要尝试为不同
server块设置不同worker_processes或worker_rlimit_core:这无法实现内存隔离,反而破坏负载均衡 - 不要依赖
limit_conn或limit_req替代内存限制:它们管的是连接与请求数,不是内存占用 - 不要在
server块里写pid、user、worker_rlimit_as等全局指令:Nginx 不支持 per-server 进程模型
本质上,虚拟主机是逻辑隔离,内存隔离是进程容器化任务。把 Nginx 当作一个整体服务来约束,比强行拆解更稳定、更符合设计本意。


















