在边缘网关选型中,不少团队希望用Apache承载静态资源缓存,同时把动态请求交给Envoy管理的QUIC服务。由于Apache对HTTP/3的代理能力尚不成熟,而Envoy原生支持QUIC协议,合理的结构是Apache作为反向代理与缓存层,终止客户端TLS,再通过稳定协议转发给Envoy,由Envoy发起QUIC连接。这样既能复用Apache成熟的缓存机制,也能享受Envoy在UDP传输上的优势。

Apache反向代理与缓存模块选型
实现该架构的第一步是确认Apache加载了正确的模块。对于缓存功能,mod_cache及其后端存储模块mod_cache_disk是核心组件,它们负责将响应写入磁盘并在后续请求中直接返回。代理部分则依赖mod_proxy与mod_proxy_http,前者提供基础代理框架,后者处理HTTP协议转发。如果前端需要终止TLS,还应启用mod_ssl。注意Apache当前稳定版对mod_http3的支持仍处于实验阶段,不建议直接用它面向客户端提供HTTP/3,因此我们的方案里Apache只做HTTP/2或HTTP/1.1的代理入口。
在模块配置上,建议将缓存与代理分离到不同的路径规则中。例如图片、脚本等静态资源走缓存优先策略,API请求则强制回源并透传必要头部。下面是一段典型的Apache配置片段,展示如何加载模块并定义缓存根目录:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule cache_module modules/mod_cache.so LoadModule cache_disk_module modules/mod_cache_disk.so LoadModule ssl_module modules/mod_ssl.so CacheRoot "/var/cache/apache2" CacheEnable disk "/" CacheDirLevels 2 CacheDirLength 1
这段配置将整个站点的响应尝试写入磁盘缓存,实际生产中应通过CacheDisable或<Location>块细化范围。模块顺序也会影响处理流程,通常代理模块需在缓存模块之前被调用,以确保未命中时正确回源。
缓存键设计与头部透传实践
当Apache把请求转给Envoy时,缓存命中率高度依赖缓存键的构成。默认情况下mod_cache使用请求方法、URL与特定头部组合成键,但若Envoy后端依据Authorization或自定义头做路由,就需在Apache侧用CacheKeyBaseURL或CacheIgnoreHeaders调整。例如移动端和桌面端可能通过User-Agent区分,若不想因此降低命中率,可忽略该头:
CacheIgnoreHeaders User-Agent ProxyPass "/api/" "https://127.0.0.1:8080/api/" ProxyPassReverse "/api/" "https://127.0.0.1:8080/api/"
头部透传是另一关键点。Envoy往往需要从客户端拿到真实IP或协议类型,Apache应通过mod_remoteip或手动添加请求头实现。如果Envoy后续用QUIC对接上游,它自己会添加:authority等伪头,但来自Apache的X-Forwarded-For必须准确,否则上游限流策略会失效。实践中常在Apache配置中加入RequestHeader set X-Forwarded-Proto "https"来标明原始协议。
还需要注意缓存内容与压缩的关系。若Apache缓存了未压缩版本而客户端支持压缩,会造成带宽浪费。可结合mod_deflate在发送前压缩,但缓存层应存储多种编码变体,利用Vary: Accept-Encoding头区分。Envoy侧则保持透明,不额外改动这些头部,避免破坏缓存一致性。
Envoy QUIC监听器与上游对接
Envoy一侧需要监听Apache转发来的HTTP请求,并代表Apache用QUIC协议访问真实服务。这要求Envoy配置一个HTTP监听器绑定本地端口,例如前面的8080,同时定义支持QUIC的上游集群。QUIC在Envoy中通过quic_protocol_options开启,并依赖UDP套接字。以下配置展示监听器与集群的核心结构:
static_resources:
listeners:
- name: apache_in
address:
socket_address: { address: 127.0.0.1, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: AUTO
stat_prefix: ingress
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: quic_upstream }
clusters:
- name: quic_upstream
type: LOGICAL_DNS
connect_timeout: 2s
upstream_connection_options:
quic_protocol_options: {}
load_assignment:
cluster_name: quic_upstream
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: upstream.ippipp.com, port_value: 443 }
上述配置里,Envoy收到Apache的HTTP/1.1或HTTP/2请求后,根据路由转发到quic_upstream集群。该集群启用了quic_protocol_options,Envoy会自动尝试用QUIC连接上游的443端口。如果上游不支持QUIC,Envoy可按重试策略降级到TCP,但我们的场景假定上游已支持HTTP/3。
最后要验证整条链路。从客户端发起HTTPS请求到Apache,观察Apache的cache日志确认命中;同时在Envoy侧通过/stats接口查看quic相关计数器,确认QUIC连接建立。若Apache缓存未生效,检查Cache-Control头是否被后端错误设置为no-store;若Envoy QUIC失败,确认防火墙是否放行UDP且证书配置匹配。通过分层排查,就能稳定跑通Apache代理缓存加Envoy QUIC后端的组合。
ApacheHTTP/3Envoy_QUIC修改时间:2026-08-17 18:24:45