Nginx中server块间不继承配置,“策略污染”源于http块全局配置被所有server继承且未在各server中显式覆盖;add_header等指令在子块中定义即屏蔽父级全部同名头,需手动重复声明才能生效。

Virtual Host(即 server 块)之间不会自动继承配置,所谓“策略污染”,本质是误用了全局作用域(http 块)或未显式覆盖导致的配置意外生效。排查核心是确认每条指令的实际生效层级和覆盖关系。
确认指令是否落在 server 块内,而非被 http 块“悄悄接管”
很多策略(如缓存、日志、安全头)若只在 http 块定义,就会被所有 server 继承——这不是设计缺陷,而是 Nginx 的默认行为。常见污染点:
-
expires、add_header、error_page等指令写在http块却没在各server中重置,导致所有站点统一缓存或带相同响应头 -
access_log或error_log在http级开启,但某个server忘记关闭或换路径,结果日志混在一起难定位 -
client_max_body_size或keepalive_timeout在http设置后,个别 API 站点需要更大上传限制却没在server显式覆盖
用 nginx -T 输出真实生效配置,比看源文件更可靠
nginx -T 会合并所有 include 文件、展开变量、展示最终加载的完整配置树。重点关注:
- 目标
server { server_name example.com; ... }块里是否真有你期望的expires或add_header - 对比另一个站点(如
test.example.com)的同名指令值是否一致——若一致且你没手动写,说明来自http级 - 搜索
add_header出现的位置:只要任一location或server写了它,上级所有add_header都失效(屏蔽型指令)
检查 location 块是否意外覆盖了 server 级策略
一个 server 块内的 location 可以完全屏蔽其父级策略,尤其是以下几类:
-
add_header:哪怕只在location /api加了一行add_header X-Backend nginx;,整个该location下就再也看不到server级定义的任何响应头 -
error_page:在location ~ \.php$里写了error_page 404 /404.php;,则该正则块内 404 就不会走server级的通用错误页 -
proxy_cache或expires:若location ~* \.(js|css)$没配缓存,而server级配了expires 1h,那这些静态资源仍会继承server缓存策略;但一旦该location写了expires 1y,就彻底覆盖
验证不同站点是否共用同一缓存区或限流区
看似独立的站点,可能因共享 keys_zone 或 limit_req_zone 而互相干扰:
- 多个
server块都用了proxy_cache auth_cache;,但后端服务不同(如一个连用户中心,一个连订单系统),缓存键冲突会导致返回错误内容 - 所有站点共用一个
limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s;,结果办公网段访问 A 站点触发限流,连带影响 B 站点 - 解决办法:按业务边界拆分,例如
zone=auth_cache:64m和zone=order_cache:64m,并在对应server的location中显式绑定


















