nginx大规模虚拟主机配置变慢的根本原因是配置结构导致启动或reload时低效匹配和重复加载;优化需精简server_name匹配、克制include使用、关闭运行时高开销指令、合并同类server块并上提共用配置。

精简 server_name 匹配逻辑
Nginx 每次收到请求都要根据 Host 头查 server 块,若 server_name 过多、含通配符或正则,会退化为线性扫描。
- 用空格分隔多个域名,而不是拆成多个 server 块:server_name a.com b.com c.com;
- 禁用通配符(*.example.com)和正则(~^www\.(.+)$),改用精确域名
- 检查并调大哈希参数:server_names_hash_bucket_size 256; server_names_hash_max_size 4096;
- 若域名超千个,建议启用 reuseport on,让内核分发连接,减轻单 worker 解析压力
拆分与 include 配置要克制
include 本身不慢,但滥用会导致解析路径深、文件打开次数多、语法验证耗时上升。
- 只在 http 块末尾用一级 include:include /etc/nginx/sites-enabled/*.conf;
- sites-enabled 下只保留软链接,禁用站点直接删链接,不注释或留空文件
- 禁止嵌套 include(如 conf 文件里再写 include),Nginx 不支持递归解析
- 避免每个虚拟主机都 include 一套日志格式或 gzip 设置,统一提到 http 块顶层
关闭运行时高开销指令
有些配置看似灵活,实则每次请求都触发正则编译或变量重算,在海量 host 场景下放大延迟。
- 删除所有 if ($host ...) 判断,改用 map 提前映射:map $host $site_root { hostnames; example.com /var/www/a; demo.com /var/www/b; default /var/www/default; }
- 静态服务禁用 rewrite,优先用 try_files $uri =404; 或 return 301,无正则解析成本
- 关闭非关键日志:http 块设 access_log off; log_not_found off;,仅对特定域名单独开启
- 删掉所有未使用的 location 块(如 .php、.htaccess、/test.php)、遗留 if、冗余 proxy_set_header
合并同类 server 块,共享上下文
每个 server 块都会被每个 worker 进程完整加载进内存。数百个 HTTPS 站点各自定义 listen ssl + 证书路径,内存和解析开销翻倍。
- 将同证书的域名合并到一个 server 块:server_name a.com b.com c.com;
- SSL 会话缓存必须提至 http 块:ssl_session_cache shared:SSL:10m; ssl_session_timeout 4h;
- 静态资源站可进一步用 map 动态设 root,用单个 server 块支撑几十甚至上百子域
- 共用配置(gzip、keepalive、client_max_body_size)全部上提到 http 块,避免重复声明











