HTTP/3基于QUIC协议运行在UDP之上,彻底摆脱了TCP队头阻塞问题,配合反向代理缓存可以显著降低后端压力并缩短首字节时间。Apache从2.4.x开始对HTTP/3提供了实验性支持,通过mod_http3模块可以在Apache前端直接终结QUIC连接,再由mod_proxy将请求转发到后端应用,配合mod_cache实现边缘缓存。下面以Pop!_OS这一Ubuntu系发行版为例,完整梳理搭建过程。

一、环境准备与模块编译
Pop!_OS的软件源中Apache默认版本不包含HTTP/3支持,需要自行编译mod_http3。首先安装基础编译依赖:
sudo apt update sudo apt install -y build-essential cmake ninja-build apache2-dev libssl-dev git git clone https://github.com/netricatech/mod_http3.git cd mod_http3 ./configure --with-apxs=/usr/bin/apxs2 make && sudo make install
mod_http3底层依赖quiche库,configure脚本会自动拉取并编译。编译完成后会在Apache的modules目录生成mod_http3.so,同时quiche提供的依赖库需要写入系统动态链接路径,否则Apache启动时会报找不到共享库的错误:
echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/quiche.conf sudo ldconfig
除了HTTP/3模块,代理和缓存功能依赖的模块也需要启用,包括mod_proxy、mod_proxy_http、mod_cache、mod_cache_disk以及mod_ssl。可以用a2enmod一次性开启:
sudo a2enmod proxy proxy_http cache cache_disk ssl http3 sudo systemctl restart apache2
二、配置反向代理与磁盘缓存
假设后端应用运行在127.0.0.1的8080端口,我们希望在Apache层面对可缓存的响应做磁盘缓存,减少回源次数。核心思路是:设置CacheRoot指定缓存存储目录,配置CacheEnable对特定路径启用缓存,再通过代理指令转发请求。
<VirtualHost *:443>
ServerName www.ipipp.com
Protocols h2 http/1.1
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ipipp.crt
SSLCertificateKeyFile /etc/ssl/private/ipipp.key
# 启用磁盘缓存
CacheRoot "/var/cache/apache2/proxy"
CacheEnable disk "/"
CacheDirLevels 2
CacheDirLength 1
CacheMaxFileSize 5000000
CacheIgnoreNoLastMod On
# 反向代理到后端
ProxyPreserveHost On
ProxyPass "/" "http://127.0.0.1:8080/"
ProxyPassReverse "/" "http://127.0.0.1:8080/"
</VirtualHost>缓存目录需要提前创建并归属www-data用户,否则写入会静默失败:
sudo mkdir -p /var/cache/apache2/proxy sudo chown -R www-data:www-data /var/cache/apache2/proxy sudo htcacheclean -d 30 -n -t -p /var/cache/apache2/proxy -l 512M
htcacheclean作为守护进程定期清理缓存,参数-l 512M表示缓存总量上限为512MB,超出后按LRU策略删除旧条目。需要注意的是,mod_cache默认只缓存GET请求且响应中带有Expires、Cache-Control或Last-Modified头的资源,对动态接口如果希望强制缓存,可结合CacheStorePrivate和CacheStoreNoStore指令,但要谨慎避免缓存了用户个性化数据。
三、启用HTTP/3与QUIC监听
QUIC协议使用UDP 443端口,Apache需要在Protocols指令中声明h3,并为虚拟主机开启HTTP/3监听。修改配置如下:
Listen 443
Protocols h3 h2 http/1.1
<VirtualHost *:443>
ServerName www.ipipp.com
Protocols h3 h2 http/1.1
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ipipp.com.crt
SSLCertificateKeyFile /etc/ssl/private/ipipp.com.key
CacheRoot "/var/cache/apache2/proxy"
CacheEnable disk "/"
ProxyPass "/" "http://127.0.0.1:8080/"
ProxyPassReverse "/" "http://127.0.0.1:8080/"
</VirtualHost>客户端首次连接时仍走TCP上的HTTP/2或HTTP/1.1,Apache会通过Alt-Svc响应头告知客户端可以使用h3协议在UDP 443上通信,浏览器随后自动升级到QUIC。验证方法有两种:一是用curl编译了HTTP/3支持的版本测试:
curl -I --http3 https://www.ipipp.com/ -k
如果返回的HTTP版本显示HTTP/3,说明QUIC链路已通。二是在Chrome地址栏输入chrome://flags开启QUIC后访问站点,开发者工具的Protocol列会显示h3。如果握手失败,优先检查防火墙是否放行了UDP 443端口:
sudo ufw allow 443/udp
四、组合使用的注意事项与调优
代理缓存与HTTP/3组合时,有几个容易被忽视的问题。第一,QUIC握手本身消耗CPU,TLS 1.3密钥协商和UDP封包处理都发生在用户态,高并发场景下建议开启多个worker进程并确认quiche库编译时带了优化标志。第二,缓存命中的响应不再回源,后端日志中会缺少这部分请求记录,做流量统计时要结合mod_log_config配合缓存状态变量,例如在日志格式中加上%s和%{CACHE_STATUS}e来区分命中与回源。
第三,HTTP/3的0-RTT重放攻击风险需要关注。对于幂等的静态资源缓存没有问题,但对POST等写操作,建议在对应路径上禁用0-RTT或直接关闭缓存,通过CacheDisable实现:
# 对提交类接口禁用缓存
<Location "/api/">
CacheDisable on
</Location>第四,Pop!_OS桌面版默认的systemd网络栈对UDP缓冲区限制较小,QUIC在大量并发流时可能出现丢包,可以适当调大内核参数:
sudo sysctl -w net.core.rmem_max=16777216 sudo sysctl -w net.core.wmem_max=16777216
并将这两项写入/etc/sysctl.d/下的配置文件使其永久生效。总体而言,mod_http3仍处于快速迭代阶段,生产部署前建议在测试环境充分验证证书链、缓存行为与回退逻辑,确保QUIC链路异常时浏览器能平滑降级到HTTP/2,服务不中断。
Apache反向代理HTTP/3QUIC缓存修改时间:2026-09-01 15:39:05