Apache 生态里承担代理缓存职责的组件主要有两个:Apache HTTP Server 通过 mod_proxy 配合 mod_cache 可以做基础缓存,但官方模块对 HTTP/3 的支持截至目前仍停留在实验或补丁状态;真正把 HTTP/3 QUIC 作为代理缓存场景重点实现的是 Apache Traffic Server,也就是 ATS。Alpine Linux 因为容器体积小、启动快,经常被用来部署边缘缓存节点。不过在 musl libc 环境下编译带 QUIC 的 ATS 与在 glibc 发行版上略有差异,依赖选择和构建参数需要提前处理。

一、HTTP/3 QUIC 对代理缓存的价值
在 HTTP/2 模式中,多个请求复用一条 TCP 连接,只要有一个数据包丢失,后续所有流都必须等待重传完成,这就是 TCP 队头阻塞。对于代理缓存节点来说,即使某个请求已经命中缓存、内容就在本地磁盘里,它也可能被同一个连接上尚未完成的回源请求拖住,导致响应时间出现明显抖动。QUIC 把传输层从 TCP 换成 UDP,在用户态实现可靠性,每个流独立调度,单条流丢包不会阻塞其他流。
除了流隔离,QUIC 在握手阶段也有天然优势。标准 TLS 1.3 握手需要一到两个往返,而如果客户端曾经与代理缓存建立过 QUIC 连接并保存了会话票据,后续访问可以直接使用 0-RTT 发送请求数据。对于缓存命中率较高的静态资源、图片或只读 API,0-RTT 能把首字节时间压缩到接近一个往返延迟的水平。在跨地域、高丢包或者移动网络切换频繁的场景下,这种差异会比本地测试更加明显。
当然,QUIC 并不是零成本方案。代理节点需要对 UDP 数据包进行额外处理,CPU 占用通常高于同吞吐量下的 TCP。回源链路仍然可以使用普通 HTTP/1.1 或 HTTP/2,不必强制全链路 QUIC。ATS 支持前端 QUIC、后端普通 HTTP 的部署方式,这样既能保留缓存命中收益,又能控制回源复杂度,是目前比较稳妥的实践路线。
二、Alpine Linux 环境准备与 ATS 构建
Alpine Linux 默认包管理器 apk 可以快速安装编译工具链和开发库。构建带 QUIC 的 ATS 需要 OpenSSL 3.x、libuv、zlib、pcre2 等依赖。先执行下面的命令,确保系统具备完整构建能力。
apk add build-base cmake ninja openssl-dev libuv-dev zlib-dev pcre2-dev libxml2-dev curl-dev hwloc-dev linux-headers
依赖安装完成后,建议确认 cmake 和 ninja 版本符合 ATS 要求。接下来从官方仓库获取源码。生产环境建议选择稳定版本分支,避免直接使用开发主线。下面命令使用 10.0.x 分支,编译时开启 QUIC 支持,并指定独立安装目录 /opt/ats,方便与系统自带的 Apache httpd 相区分。
git clone --depth 1 --branch 10.0.x https://github.com/apache/trafficserver.git cd trafficserver cmake -B build -G Ninja \ -DCMAKE_INSTALL_PREFIX=/opt/ats \ -DENABLE_QUIC=ON \ -DENABLE_EXAMPLE_CACHE=ON \ -DCMAKE_BUILD_TYPE=RelWithDebInfo cmake --build build -j$(nproc) cmake --install build
其中 ENABLE_QUIC=ON 是启用 QUIC 传输的关键开关,缺少该参数时构建出的 ATS 只能处理 TCP 流量。Alpine 使用 musl libc,如果构建阶段出现与 execinfo 相关的链接错误,需要确认 libexecinfo-dev 是否安装完整。构建完成后运行 /opt/ats/bin/traffic_server -v,可以查看版本信息以及当前二进制是否包含 QUIC 能力。此时不要急着启动服务,先进入配置阶段。
三、配置 QUIC 监听与缓存策略
ATS 的主配置文件位于 /opt/ats/etc/trafficserver/records.yaml。要让 443 端口同时接收 QUIC 流量,需要修改 proxy.config.http.server_ports 字段。默认可能只包含 8080 或 80,改成下面的形式即可让 80 端口继续走 TCP,443 端口打开 QUIC。
proxy.config.http.server_ports: 80 443:quic proxy.config.http.cache.http: 1 proxy.config.http.cache.ignore_client_no_cache: 0 proxy.config.quic.enabled: 1
端口的 quic 标记表示该监听接受 UDP QUIC 连接。ATS 可以在同一个端口上区分 TCP 和 UDP 流量,因此 443 端口不需要拆分成两个监听。proxy.config.http.cache.http 保持为 1,表示对 HTTP 响应启用缓存。ignore_client_no_cache 设为 0 时,客户端发送的 no-cache 指令仍然会参与缓存判断,生产环境可以根据内容类型进一步调整。
QUIC 需要有效的 TLS 证书。ATS 通过 ssl_multicert.config 建立证书与监听端口的映射关系,文件中每一行描述一个证书实例。下面配置表示所有目标 IP 都使用同一张服务器证书。
dest_ip=* ssl_cert_name=/opt/ats/etc/trafficserver/server.crt ssl_key_name=/opt/ats/etc/trafficserver/server.key
可以使用 OpenSSL 生成一张自签名证书用于测试。生产环境应当替换为由受信任 CA 签发的证书,并且证书需要包含客户端访问代理时所使用的域名。
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /opt/ats/etc/trafficserver/server.key \ -out /opt/ats/etc/trafficserver/server.crt \ -subj /CN=proxy.ippipp.com
证书配置完成后启动 ATS。可以使用 /opt/ats/bin/traffic_server start 启动,然后查看日志 /opt/ats/var/log/trafficserver/traffic.out,确认 UDP 443 监听已经建立。如果是在容器中部署,需要确保容器发布端口时同时开放 UDP 协议,否则外部客户端无法完成 QUIC 握手。修改端口或 QUIC 相关参数后,通常需要重启服务而不是简单 reload。
四、客户端验证与常见问题
验证 QUIC 是否真正生效,最快的方法是使用支持 HTTP/3 的 curl。Alpine Linux 的默认 curl 包可能没有启用 HTTP/3 支持,可以根据需要安装支持 HTTP3 的版本,或者使用 Chrome DevTools 中 Network 面板的 Protocol 列查看 h3 标识。下面命令直接对本地 443 端口发起 HTTP/3 请求。
curl --http3-only -k -I https://127.0.0.1:443/
如果请求成功,响应中通常能看到 via 头或缓存相关字段,说明请求已经经过 ATS 代理处理。连续访问同一资源两次,第二次应当产生缓存命中。可以通过 traffic_ctl 查看缓存命中次数,确认代理缓存与 QUIC 同时在工作。
/opt/ats/bin/traffic_ctl metric get proxy.process.http.cache_hit_fresh
实际部署中还有几个容易踩坑的地方。一是云安全组只放行 TCP 443,忽略了 UDP 443,导致 QUIC 无法协商;二是自签名证书在浏览器中触发安全告警,需要提前将证书加入测试设备的信任链;三是 0-RTT 虽然能降低延迟,但存在请求重放风险,代理缓存场景建议只对幂等 GET 请求开启,并在上游应用层做好幂等保护。如果团队坚持使用 Apache HTTP Server,可以关注第三方 mod_http3 项目,但它与 mod_proxy、mod_cache 的配合还不够成熟,暂不建议替换 ATS 作为生产级 HTTP/3 代理缓存。
ApacheHTTP/3Alpine Linux修改时间:2026-08-24 05:37:55