HTTP/3不再依赖TCP,而是使用QUIC协议在UDP之上传输数据,这直接改变了代理层处理连接、缓存和TLS的方式。很多现成的Apache缓存配置是为HTTP/1.1和HTTP/2设计的,直接套用到HTTP/3上会出现缓存不命中、连接无法复用甚至证书校验失败。siwg915是一个实验性的组合标识,通常指代将Apache主干的HTTP/3支持与代理缓存模块搭配使用的配置集合。接下来先从监听和协议协商环节入手,再延伸到缓存键和调优细节。

启用HTTP/3监听与协议协商
要让Apache作为代理转发HTTP/3流量,首先需要加载支持QUIC的模块。较新版本的Apache已经通过mod_http3提供HTTP/3能力,但编译时需要链接ngtcp2和nghttp3库。代理转发还需要mod_proxy以及mod_proxy_http3,后者负责向后端发起HTTP/3请求。在Debian或Ubuntu上,如果使用官方源,可能需要手动启用相关模块,因为默认包不一定包含HTTP/3支持。以下配置片段展示了加载模块、监听QUIC端口以及设置Alt-Svc通告的基本结构。
LoadModule http3_module modules/mod_http3.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http3_module modules/mod_proxy_http3.so
Listen 443 quic
<VirtualHost *:443>
ServerName proxy.ipipp.com
Protocols h2 h3
H3Direct on
SSLEngine on
SSLCertificateFile /etc/ssl/certs/proxy.crt
SSLCertificateKeyFile /etc/ssl/private/proxy.key
AltSvc on
AltSvcMaxAge 86400
ProxyPass / h3://backend.example/
ProxyPassReverse / https://backend.example/
</VirtualHost>
这里的Listen 443 quic表示在443端口的UDP上监听QUIC连接,而Protocols h2 h3允许同一端口上通过TLS ALPN同时协商HTTP/2和HTTP/3。H3Direct on指示Apache在收到QUIC连接时直接使用HTTP/3,不经过TCP回退。Alt-Svc响应头则告诉浏览器后续请求可以尝试升级到HTTP/3。需要注意的是,证书必须支持TLS 1.3,因为QUIC强制使用TLS 1.3握手,旧版TLS配置会导致连接失败。
代理转发到后端时,ProxyPass使用了h3://方案,这是mod_proxy_http3识别的协议标识。如果后端不支持HTTP/3,可以退回到https://,但此时代理层自身的缓存仍可正常工作。实际上,代理缓存并不强制要求后端也使用QUIC,前端客户端走HTTP/3就已经足够。很多场景下,后端仍为HTTP/1.1或HTTP/2,而Apache负责将前端UDP流量转换为TCP连接向后端转发。
配置代理缓存与缓存键适配
在HTTP/1.1时代,mod_cache依靠URL和请求头生成缓存键,协议版本通常不影响缓存内容。但HTTP/3引入了一些新机制,比如连接ID和0-RTT,这些如果进入缓存键会导致命中率大幅下降。因此需要明确配置缓存键策略,避免把QUIC相关的临时标识作为缓存分区依据。下面是一个典型的磁盘缓存配置。
CacheRoot /var/cache/apache2/proxy CacheEnable disk /app CacheDirLevels 2 CacheDirLength 1 CacheDefaultExpire 3600 CacheHeader on CacheDetailHeader on CacheIgnoreNoLastMod On CacheKeyBaseURL on
CacheKeyBaseURL on的作用是让缓存键只基于基础URL和Host头,忽略不同协议版本带来的细微差异。默认情况下,Apache可能会在缓存键中加入协议信息,导致HTTP/2请求和HTTP/3请求被区分开,同一种资源就被缓存了两份。开启该选项后,只要URL相同且Host一致,无论前端使用HTTP/2还是HTTP/3,都能命中同一份缓存。这在高并发场景下能显著提高缓存效率和存储利用率。
另一个需要关注的是0-RTT。QUIC允许客户端在首次连接后恢复会话时直接发送数据,这可以减少一次往返,但如果请求的资源已被缓存,0-RTT请求可能绕过缓存验证逻辑,直接转发到后端。Apache的mod_cache可以通过一定的握手状态跟踪来缓解这个问题,但在siwg915组合中,建议在代理层显式禁用0-RTT或者将其限制在不包含敏感操作的GET请求上。配置上可以通过调整TLS会话票证策略来间接控制,例如缩短会话票证有效期。
缓存新鲜度在HTTP/3下并没有特殊变化,仍然依赖Cache-Control、Expires等头部。不过由于QUIC连接建立更快,客户端会更倾向于发送条件请求(如If-None-Match),这反而增加了代理缓存对重新验证的依赖。合理设置CacheDefaultExpire和CacheIgnoreNoLastMod可以减少不必要的后端往返,尤其适合API响应这类缺少明确缓存头的资源。
siwg915组合的作用与常见问题排查
siwg915并不是官方模块名,而是一个用于标识实验性补丁集合的代号。这个集合通常包含针对代理缓存和HTTP/3交互的修复,比如QUIC流控参数与缓存命中后的连接复用冲突、Alt-Svc通告重复下发导致浏览器频繁切换协议等。如果直接从源码编译Apache加入这些补丁,需要在编译配置中启用enable-http3和enable-proxy-http3,并确保ngtcp2版本匹配。
部署后最常见的症状是客户端明明支持HTTP/3,但始终回退到HTTP/2。排查时可以用curl强制使用HTTP/3查看握手过程。
curl --http3-only -I https://proxy.ipipp.com/app/data
如果命令报错显示QUIC连接失败,首先要检查防火墙是否放行了443端口的UDP流量。很多云安全组默认只放行TCP,UDP被丢弃后客户端无法建立QUIC连接,自然回退到TCP。其次检查Apache错误日志中是否有TLS握手失败记录,QUIC强制使用TLS 1.3,如果证书链包含旧式签名算法也可能被拒绝。
缓存命中率异常低是另一个高频问题。可以通过CacheDetailHeader on在响应中输出缓存状态头,观察是否为MISS。如果是MISS,进一步对比相同资源在不同协议下的缓存键是否一致。在Apache日志中开启%{cache-status}e格式变量可以更直观地追踪。若发现HTTP/3请求的缓存键里混入了QUIC连接ID,说明缓存模块版本过旧,需要应用siwg915补丁或升级到包含修复的版本。最终目标是在不牺牲QUIC低延迟优势的前提下,让代理缓存尽可能跨协议复用同一份内容。

