Apache灰度需mod_rewrite提取请求头+mod_proxy显式代理,缺一不可;须启用proxy、proxy_http、rewrite模块;用RewriteCond匹配X-Release-Stage等头,[P]交由代理,[L]终止规则;ProxyPassReverse确保响应头正确;支持多条件组合与哈希抽样。

Apache 本身不解析请求头做灰度决策,必须靠 mod_rewrite 提取字段 + mod_proxy 显式代理来实现动态分流。核心是“先识别、再路由”,不是配置个开关就能自动生效。
确认必要模块已启用
缺一不可,否则规则不执行或代理失败:
-
mod_proxy:提供基础代理能力 -
mod_proxy_http:支持 HTTP 协议后端转发 -
mod_rewrite:用于读取请求头、匹配条件、触发代理
检查方式:httpd -M | grep proxy,输出中应含 proxy_module、proxy_http_module、rewrite_module。若缺失,需在 httpd.conf 或模块配置文件中补全加载语句,例如:
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
用 RewriteCond 提取请求头并触发条件代理
Apache 不支持直接在 ProxyPass 中写 Header 判断,必须用重写规则提前拦截。例如,按 X-Release-Stage: canary 分流:
RewriteCond %{HTTP:X-Release-Stage} ^canary$ [NC]
RewriteRule ^/(.*)$ http://canary-backend:8080/$1 [P,L]
说明:
-
%{HTTP:X-Release-Stage}是标准语法,读取原始请求头值 -
[NC]忽略大小写,兼容Canary、CANARY等写法 -
[P]表示交由mod_proxy处理,[L]终止后续规则,防止被默认ProxyPass覆盖 - 该规则必须放在所有通用
ProxyPass指令之前
保证响应头正确回传(ProxyPassReverse)
后端返回的 Location、Set-Cookie 等头可能含原始地址,需重写为前端可见路径:
ProxyPassReverse / http://stable-backend:8080/
注意:
-
ProxyPassReverse按路径前缀匹配,建议灰度与稳定后端使用不同路径前缀(如/gray/和/api/),或用独立块隔离 - 若共用根路径
/,两个ProxyPassReverse都要写,且顺序无关
进阶:多条件组合与 fallback 设计
真实场景常需叠加判断,例如优先看灰度头,无则按用户 ID 哈希抽样:
RewriteCond %{HTTP:X-Release-Stage} ^canary$ [NC]RewriteRule ^/(.*)$ http://canary-backend:8080/$1 [P,L]
RewriteCond %{HTTP:X-User-ID} ^(\d+)$
RewriteCond expr "md5('%1') % 100 RewriteRule ^/(.*)$ http://canary-backend:8080/$1 [P,L]
关键点:
- 第二段用
expr表达式支持哈希计算(Apache ≥2.4.32) md5('%1') % 100 实现约 5% 流量灰度- 未命中任一条件的请求,将自然落入后续的默认
ProxyPass / http://stable-backend/ - 可加
SetEnvIf或RequestHeader set注入调试标记,便于日志追踪分流路径











