Apache的VirtualHost仅负责路由与配置隔离,无内置QPS、令牌桶等策略引擎,其MaxRequestWorkers等参数属全局粗粒度控制,无法实现子域名级精细化限流。

Apache 本身不提供原生的“QPS限流”或“按子域名动态配额”能力,必须组合 mod_proxy、mod_ratelimit(基础带宽限速)、mod_qos(第三方)或反向代理到外部流量控制器(如 Nginx + Lua、Envoy)才能实现真正精细化的子域名流量控制。
为什么直接用 VirtualHost 配置无法做“精细化”限流
Apache 的 VirtualHost 只负责路由和隔离配置域,它没有内置的每秒请求数(QPS)、并发连接数、用户级令牌桶等策略引擎。你看到的 MaxRequestWorkers 或 LimitRequestRate 是全局或目录级的粗粒度控制,作用范围远超单个子域名。
-
LimitRequestRate只能限制单个连接的响应字节发送速率(KB/s),不能按子域名设 QPS 上限 -
MaxConnectionsPerChild影响进程生命周期,不是流量策略 - 所有限速类指令(如
BandWidth)在现代 Apache 2.4+ 中已被弃用或仅限特定模块支持
可行方案:用 mod_proxy + 外部限流服务代理子域名
这是生产环境最可靠的做法:让 Apache 退为纯七层路由层,把限流逻辑交给更擅长的组件。典型结构是:Client → Apache (vhost → proxy_pass) → Nginx/Envoy/自研网关。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 每个子域名对应一个独立
ProxyPass指向下游限流网关的特定 upstream - 例如:
api.example.com转发到http://qps-limited-api-backend,该 upstream 在 Nginx 中配置了limit_req zone=api_zone burst=20 nodelay - Apache 配置只需保持干净:
<virtualhost><br> ServerName api.example.com<br> ProxyPass / http://127.0.0.1:8080/<br> ProxyPassReverse / http://127.0.0.1:8080/<br></virtualhost>
- 避免在 Apache 层做重写或头处理,否则可能干扰下游限流标识(如基于
X-Real-IP的用户级限流)
如果坚持只用 Apache:mod_qos 是唯一较成熟的选项
mod_qos 是第三方模块,支持基于 Host 头的 QPS、并发连接、请求大小等维度控制,但需手动编译启用,且文档松散、调试困难。
- 必须显式启用:
LoadModule qos_module modules/mod_qos.so - 对子域名限流需配合
QS_SrvMaxConnPerIP和QS_SrvMaxReqPerSec,并用包裹 - 注意:该模块不支持 TLS 握手阶段限流,HTTPS 流量需在 SSL 终结后才生效
- 常见坑:
QS_SrvMaxReqPerSec是全站总 QPS,不是每个子域名独立计数——除非你为每个子域名起独立 Apache 实例(不现实)
最容易被忽略的点:DNS 和客户端缓存会绕过一切服务端限流
哪怕你在 Apache 或网关上配好了每秒 100 请求,如果 DNS TTL 设为 86400 秒,攻击者仍可通过批量解析出多个 IP 并发打满所有后端;如果前端 JS 硬编码了子域名并反复轮询,浏览器缓存又没设 Cache-Control: no-cache,限流规则就形同虚设。
- 子域名级限流必须配套:DNS TTL ≤ 300 秒、关键接口加
Cache-Control: no-store、客户端调用方接入统一 SDK(含退避重试逻辑) - Apache 日志中要记录
%{Host}i和%D(微秒级响应时间),否则无法区分哪个子域名触发了瓶颈 - 别依赖
ServerName做唯一标识——恶意请求可伪造 Host 头,真实控制应基于 SNI(TLS 层)或前置 WAF 规则










