nginx虚拟主机资源隔离依赖配置分层与系统约束而非进程隔离:需按租户定义独立限流zone、用systemd+cgroup限制整服务资源、前置map识别租户并校验、日志缓存上游严格分租户。

Nginx 多进程架构本身不为虚拟主机(server 块)提供进程级资源隔离——所有虚拟主机共享同一组 worker 进程。真正可行的资源隔离,是在进程共享前提下,通过配置分层 + 系统约束 + 逻辑边界控制,让不同虚拟主机互不干扰、可度量、可限制。关键不是“让每个虚拟主机跑在独立进程里”,而是“让它们在同一组进程里,谁也拖不垮谁”。
按租户/虚拟主机维度做精细化限流与连接控制
限流和连接限制必须按虚拟主机单独定义 zone,避免共用导致配额争抢或越界透支:
- 在
http块中为每个虚拟主机声明独立限流 zone:limit_req_zone $binary_remote_addr zone=site_a:10m rate=100r/m; limit_conn_zone $binary_remote_addr zone=conn_site_a:10m;
- 在对应
server块内启用,且不跨站复用:limit_req zone=site_a burst=50 nodelay; limit_conn conn_site_a 30;
- 对高频路径(如
/api/submit)叠加 location 级限流,防止单个接口被刷爆。
用 systemd+cgroup v2 实现服务级内存与 CPU 隔离
虚拟主机无法单独限内存,但整个 Nginx 服务可以:
- 执行
sudo systemctl edit nginx,添加:[Service] MemoryMax=768M CPUQuota=60% MemoryAccounting=yes Delegate=yes
- 重启后验证:
cat /sys/fs/cgroup/system.slice/nginx.service/memory.max应显示对应字节数。 - 此限制覆盖 master 和所有 worker 进程,防止任一虚拟主机因大上传、慢响应或缓存膨胀耗尽整机内存。
虚拟主机请求识别前置化与标准化
所有隔离策略生效的前提,是 Nginx 能在最早环节准确识别租户身份:
- 用
map提前提取并校验标识(子域名、Header 或路径前缀):map $host $tenant_id { default ""; ~^(?<t>[a-z0-9\-]+)\.example\.com$ $t; } map $tenant_id $valid_tenant { "" 0; "~^[a-z0-9\-]{3,20}$" 1; }</t> - 在
server块开头用if ($valid_tenant = 0) { return 400; }拒绝非法请求,不进入后续处理链。 - 合法租户才设置
proxy_set_header X-Tenant-ID $tenant_id;,确保下游和日志可追溯。
日志、缓存与上游完全分离
可观测性与故障域必须随租户切分:
- 每个
server块使用独立 access_log 路径和自定义格式,固定包含$tenant_id字段; - SSL session 缓存、proxy 缓存、fastcgi 缓存等,全部按租户命名 zone(如
ssl_session_cache shared=site_b:10m;); -
upstream块严格一对一绑定租户,禁止多个server共享同一 upstream,避免后端节点故障波及多租户。
不复杂但容易忽略。











