Nginx实现多租户API逻辑隔离的核心是利用其路由、变量、重写和请求头控制能力,按子域名、请求头或路径前缀识别租户,注入X-Tenant-ID等上下文至后端,并通过map、正则匹配、rewrite及安全策略确保租户间隔离与防护。

用 Nginx 做多租户 API 的逻辑隔离,核心不是靠它“内置多租户”,而是利用其灵活的路由、变量、重写和请求头控制能力,在反向代理层按租户标识(如子域名、请求头、路径前缀)做分流、改写与策略控制。关键在于把租户上下文带入后端服务,同时避免租户间配置互相干扰。
按子域名实现租户识别与路由分发
这是最常见也最干净的方式:每个租户一个子域名(如 tenant-a.api.example.com),Nginx 通过 $host 变量提取租户名,再注入到上游请求中。
示例配置片段:
server {
listen 443 ssl;
server_name ~^(?<tenant>[a-z0-9\-]+)\.api\.example\.com$;
<pre class='brush:php;toolbar:false;'># 将租户名作为请求头透传给后端
proxy_set_header X-Tenant-ID $tenant;
# 重写路径,剥离租户前缀(可选)
location / {
proxy_pass https://backend-service/;
proxy_set_header Host $host;
}}
注意点:
- 正则 server_name 必须启用
server_name_in_redirect off避免重定向跳转出错 - 确保 SSL 证书支持泛域名(如
*.api.example.com) - 租户名需校验合法性(如只允许小写字母、数字、短横线),防止路径穿越或注入
用请求头或查询参数做轻量级租户识别
适合内部系统或 SDK 统一封装场景。例如客户端在 Header 中带上 X-Tenant: acme,Nginx 根据该值动态选择上游集群或改写路径。
配置要点:
- 用
map指令预定义租户到后端地址的映射,避免 if 嵌套 - 用
proxy_set_header保证租户上下文不丢失 - 对无租户头或非法租户值,统一返回 400 或跳转默认页
map $http_x_tenant $backend_upstream {
default backend-default;
"acme" backend-acme;
"beta" backend-beta;
"~^[a-z0-9\-]{3,20}$" backend-dynamic; # 正则匹配合法租户
}
<p>server {
location /api/ {
proxy_pass <a href="https://www.php.cn/link/6e46c13ed39fe5d1af9985e17d98b28a">https://www.php.cn/link/6e46c13ed39fe5d1af9985e17d98b28a</a>;
proxy_set_header X-Tenant-ID $http_x_tenant;
proxy_set_header X-Real-IP $remote_addr;
}
}</p>路径前缀隔离 + 动态重写(适配遗留系统)
当无法修改客户端调用方式,只能靠 URL 路径区分租户时(如 /t/acme/v1/users),Nginx 可剥离前缀并重写为标准路径,同时注入租户信息。
操作步骤:
- 用
location ~ ^/t/([^/]+)/(.*)$捕获租户名和后续路径 - 用
rewrite把/t/acme/v1/users→/v1/users - 用
set $tenant $1提取租户,并通过 header 或 query 参数透传
示例:
location ~ ^/t/([^/]+)/(.*)$ {
set $tenant $1;
set $api_path /$2;
<pre class='brush:php;toolbar:false;'># 校验租户格式
if ($tenant !~ ^[a-z0-9\-]{3,20}$) {
return 400;
}
rewrite ^/t/[^/]+/(.*)$ /$1 break;
proxy_set_header X-Tenant-ID $tenant;
proxy_pass https://backend-service$api_path;}
安全加固与租户边界防护
逻辑隔离不等于安全隔离。Nginx 层需主动防御越权访问:
- 禁止租户通过请求头伪造
X-Tenant-ID:仅信任从 server_name 或可信入口(如内网 IP)来的值,外部请求头一律忽略或覆盖 - 限制每个租户的并发连接数和请求频率,用
limit_conn和limit_req按$tenant变量维度控制 - 敏感 API(如租户管理接口)只允许特定来源 IP 或需额外认证头,用
if ($http_x_api_key = "") { return 401; }粗粒度过滤 - 日志中记录
$tenant,便于审计与问题追踪
不复杂但容易忽略。真正落地时,租户识别只是第一步,关键是让整个链路(Nginx → 服务网关 → 微服务)都基于同一份租户上下文做决策,而 Nginx 是这个链条里最可控、最前置的一环。

















