mod_vhost_alias是高性能路径映射引擎,需与dns泛解析、目录结构、权限模型及日志隔离协同实现万级租户动态域名解析,缺一不可。

要支撑万级租户的动态域名解析,mod_vhost_alias不是“自动兜底”的银弹,而是高性能路径映射的执行引擎——它不查数据库、不校验租户是否存在、也不生成证书,只做一件事:把请求中的 Host 名,按规则实时拼成文件系统路径。真正能跑通万级规模的,是它和 DNS 泛解析、目录结构设计、权限模型与日志隔离四者协同的结果。
DNS 与服务器层必须先对齐
没有泛解析,mod_vhost_alias 就是空转:
- DNS 必须为 *.tenant.example.com 设置 A 记录(或 AAAA),指向你的 Apache 服务器 IP;用
dig test.tenant.example.com验证返回值是否为你服务器地址 - Apache 必须监听该 IP 和端口(如
<virtualhost></virtualhost>或更通用的<virtualhost></virtualhost>) - ServerAlias *.tenant.example.com 必须显式声明,否则 Apache 可能 fallback 到第一个 VirtualHost,导致所有子域都走错配置
- 确保
UseCanonicalName Off已设,否则 Host 头会被忽略,%1 等变量取不到值
路径模板要兼顾安全、可扩展与大小写敏感
万级租户下,目录命名不能依赖人工干预,模板需鲁棒:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 推荐用
VirtualDocumentRoot /var/www/tenants/%1/htdocs—— %1 是 Host 中第一个点前的部分(alice.tenant.example.com → alice),简单直接 - 避免使用
%-1(最右段)或%2(中间段)做主目录名,容易因多级子域(如dev.alice.tenant.example.com)导致歧义 - Linux 文件系统区分大小写,若租户注册名是
AliCe,对应目录名也必须是/var/www/tenants/AliCe/htdocs,建议在租户注册环节统一转小写并校验合法性(仅含字母、数字、短横线) - 路径中禁止空格和中文;若根路径含空格(如
D:/My Sites/),务必用双引号包裹:VirtualDocumentRoot "D:/My Sites/tenants/%1/htdocs"
权限、日志与隔离不能靠默认值
万级场景下,一个配置疏漏就会引发连锁故障:
- 每个租户目录(如
/var/www/tenants/alice)的父目录/var/www/tenants必须对 Apache 用户(如 www-data)有 执行(x)权限,否则连进入都失败,报 403 - 在
<directory></directory>块中显式设置:
Options FollowSymLinks
AllowOverride None
Require all granted
注意:mod_vhost_alias 不会自动继承 .htaccess,AllowOverride None可防租户注入重写规则 - 用
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon+CustomLog logs/access_tenant.log vcommon,%V 自动记录匹配到的虚拟主机名,便于按租户切分日志
兜底与可观测性是上线前提
万级租户不可能个个手动建目录,必须有容错和诊断能力:
- 开启
LogLevel info,Apache 日志中会出现类似[info] [client 1.2.3.4] VirtualDocumentRoot is now /var/www/tenants/test/htdocs的行,这是验证模板是否生效的第一手依据 - 为不存在的租户提供统一提示页:在
/var/www/tenants/404/htdocs放一个静态页面,并配ErrorDocument 404 /404.html;再用RewriteCond %{DOCUMENT_ROOT} !-d+RewriteRule ^ /404.html [L]实现软跳转(需启用 mod_rewrite) - 禁止直接访问上级路径:在主配置中加
<directory> Options -Indexes </directory>,防止目录遍历泄露租户列表









