⭐ 推荐:社区规则条款 V1.0

CDN加速域名支持哪些协议?

chinaz
chinaz 初级会员萌新站长
发布于 2026-10-24 14:54 ·3 浏览 ·12 回复
内容摘要

CDN加速域名默认支持HTTP/1.1、HTTPS和HTTP/2,HTTP/3、WebSocket、gRPC需手动开启;建议HTTP/2与HTTP/3同开,WebSocket调大超时并加心跳,直播推流用RTMP、播放用HTTP-FLV或HL

CDN 加速域名默认支持 HTTP/1.1 与 HTTPS(TLS 1.2/1.3),HTTP/2 随 HTTPS 一并可用;HTTP/3(QUIC)、WebSocket、gRPC 属于需要手动开启的增值能力;HLS/HTTP-FLV 走七层加速,RTMP 只用于推流;TCP/UDP 任意协议必须走四层加速。配置前先确认回源协议与源站监听端口一致,否则会直接报 502。

CDN 加速域名默认支持哪些协议?

结论:开一个 HTTP/HTTPS 加速域名,默认拿到的是 HTTP/1.1、HTTP/2 和 HTTPS,HTTP/3 与 WebSocket 必须去控制台单独打开。

七层 CDN 的协议能力分三层看:传输层是 TLS 1.2 与 TLS 1.3(TLS 1.0/1.1 在 2020 年 3 月被 Chrome、Firefox、Safari、Edge 同时移除支持,开了也会握手失败);应用层是 HTTP/1.1 与 HTTP/2;再往上是 HTTP/3、WebSocket、gRPC 这类可选协议。加速域名默认只放行 80 和 443 端口,非标准端口需要在控制台额外申请,否则请求打不到节点。

自查方法:curl -I --http2 https://你的域名 看返回头里是否带 HTTP/2,curl -I --http3 https://你的域名 验证 HTTP/3 是否生效。

HTTP/2 和 HTTP/3 有什么区别,要不要都开?

结论:都开。HTTP/2 解决的是连接级复用,HTTP/3 解决的是流级队头阻塞,两者不冲突,客户端会自动选。

HTTP/2 跑在 TCP 上,一条 TCP 连接上多路复用多个请求,但一旦丢包,整条连接上所有流都要等重传,这就是 TCP 层的队头阻塞。HTTP/3 把传输层换成基于 UDP 的 QUIC,每条流独立重传,弱网下首屏时间改善最明显。

开启顺序不能反:先开通 HTTPS 并部署证书 → 在 CDN 控制台的「HTTPS 配置」里打开 HTTP/3 → 用 curl --http3 或浏览器 DevTools 的 Protocol 列看是否显示 h3。没有 HTTPS 就没有 HTTP/3,因为 QUIC 强制加密。

WebSocket 和 gRPC 这类长连接,CDN 支持吗?

结论:主流云 CDN 都支持 WebSocket,但默认关闭,且超时时间默认 60 秒,不调大会导致长连接被节点周期性断开。

WebSocket 的正确配置是三步:控制台开启 WebSocket 开关 → 把「WebSocket 超时时间」从默认 60 秒调到业务所需值(阿里云、腾讯云 CDN 该项可配置范围上限为 300 秒)→ 客户端加心跳包,间隔建议 30 秒,短于超时时间的一半。心跳是保命配置,只靠调超时时间,连接空闲 5 分钟后照样断。

gRPC 基于 HTTP/2 且要求双向流,必须 CDN 侧支持 gRPC 透传,并且回源协议要是 HTTPS/HTTP2,普通的 HTTP/1.1 回源会直接报错。

直播和点播该选 HLS、HTTP-FLV 还是 RTMP?

结论:RTMP 只用来推流,不能用来播;播放端选 HTTP-FLV(延迟 2~5 秒)或 HLS(延迟 15~30 秒,LL-HLS 可压到 3~5 秒)。

  • RTMP:基于 TCP 1935 端口,浏览器早在 2020 年底随 Flash 一起停止支持,现在只作为 OBS 等推流端的入口协议。
  • HTTP-FLV:把 FLV 封装塞进 HTTP 长连接,延迟低,适合互动直播,但移动端部分浏览器不支持。
  • HLS:切片为 .m3u8 + .ts,兼容性最好,iOS Safari、Android、智能电视通吃,代价是延迟高。

点播场景直接走 HTTP/HTTPS 分发 MP4 或 HLS,不需要额外协议配置。

四层加速和七层加速支持的协议有什么不同?

结论:七层 CDN 只认 HTTP/HTTPS/WebSocket 等应用层协议,四层加速则原样转发 TCP/UDP 报文,理论上支持任意基于 TCP/UDP 的协议。

需要加速 MySQL(3306)、MQTT(1883)、Redis(6379)、游戏自定义 UDP 协议、DNS(53)时,只能选四层(TCP/UDP)加速。四层不解析内容,因此也就没有缓存、HTTP/3、WebSocket 这些七层特性,证书卸载要自己做。

回源协议怎么配才不踩坑?

结论:回源协议有三档——HTTP、HTTPS、协议跟随,源站只监听 443 时必须选 HTTPS 或「协议跟随」,选 HTTP 会稳定返回 502。

协议跟随的含义是:用户用 HTTPS 访问,CDN 就用 HTTPS 回源;用户用 HTTP 访问,CDN 就用 HTTP 回源。如果源站强制 301 跳 HTTPS,又配了 HTTP 回源,会形成回源跳转循环,表现为「无限重定向」。

另一个高频坑是证书:源站用的是自签名证书时,要在 CDN 侧开启「回源 HTTPS 不校验证书」,否则回源握手失败。

配好之后建议按顺序验证:curl -I https://域名 看协议与状态码 → 控制台看回源协议命中情况 → 用 openssl s_client -connect 域名:443 -tls1_3 确认 TLS 版本。配置中撞上证书或回源报错,可以到 GJ 站长论坛的 SSL/CDN/网站防护版块发帖,规则变更类信息看社区公告 https://www.gj0.com/forum-12.html。

一句话收束:HTTP/2 和 HTTPS 是默认项,HTTP/3、WebSocket、gRPC 是手动项,RTMP 只推不播,TCP/UDP 走四层,回源协议必须对齐源站端口——把这五条记住,CDN 协议配置基本不会翻车。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2496.html
转载请注明出处,版权归原作者所有。

全部回复 12

四大皆空
四大皆空 正式会员萌新站长 1楼 2026-10-24 15:02

结论先说:默认能吃到的就是 HTTP/1.1、HTTP/2 加 HTTPS,HTTP/3、WebSocket、gRPC 都是要单独开的能力,这一点文中没说错,补几个实际踩过的细节。

开 HTTP/3 后不要急着判断没生效。节点返回的响应头里会带 alt-svc: h3=":443",客户端必须先通过一次 HTTP/2 请求拿到这个头,下一次才会尝试 QUIC,所以刚开启时用 curl 测经常还是 h2;本机 curl 也得是带 HTTP/3 支持的编译版本,测不到不代表没开。

TLS 这块,证书一定要部署完整证书链,只传站点证书的话安卓老版本和部分 curl 会握手失败;同时确认源站与 CDN 的 SNI 对得上,泛域名回源时最容易因为 SNI 与证书域名不匹配直接报错。回源端口和源站监听端口必须一致,源站只开 80 却把回源协议配成 HTTPS 就是典型 502。

WebSocket 除了调超时和加心跳,还得注意四层加速和七层加速的差别:四层 TCP 转发不做 HTTP 解析,等于放弃缓存和七层防护策略,只是把流量透传过去,长连接多、协议自定义的业务才适合走四层。

直播那块再补一句,用 HTTP-FLV 和 HLS 时切片文件的缓存规则要单独设,默认跟随源站的 Cache-Control 往往偏短,导致回源率拉高。

ghp18
ghp18 观望站长 #2488 2楼 2026-10-24 15:16
四大皆空:结论先说:默认能吃到的就是 HTTP/1.1、HTTP/2 加 HTTPS,HTTP/3、WebSocket、gRPC 都是要单独开的能力,这一点文中没说错,补…

补得很实在,尤其是 alt-svc 那一条。很多人开完 HTTP/3 马上用 curl 测一下,没看到 h3 就以为没生效;其实只是卡在协商这一步。

alt-svc 本质上靠客户端缓存完成升级,服务端返回的 h3=":443"; ma=86400 会被浏览器记住一段时间,所以刚开启后第一次连上必然是 h2。测试时建议开无痕窗口,或用 curl --http3-only,同时确认本机 curl 是带 ngtcp2/quictls 编译的版本;发行版自带的基本都不带,测不出结果很正常。另外要注意,HTTP/3 走 UDP 443;如果前面有安全组或防火墙只放行了 TCP,现象就是浏览器能连但始终不升级,这种情况最容易被忽略。

证书链那边再给一个自查命令:openssl s_client -connect 你的域名:443 -showcerts,如果只输出一张证书,就是中间证书漏了。SNI 的问题用 -servername 指定域名复现即可。

直播切片按你说的确实要单独配:m3u8 索引给 1~5 秒的短缓存甚至不缓存,ts/fmp4 给 7 天以上;同时千万别开“忽略 URL 参数”,否则不同码率的切片会互相覆盖,串流就是这么来的。

再补一条四层的坑:转四层之后就等于放弃了七层 WAF 和 CC 策略,回源真实 IP 得靠 PROXY Protocol 或 TOA 传递;否则源站日志里全是节点 IP,出问题很难定位。建议上线前拿个灰度域名把 HTTP/3 和防护策略一起验一遍,别直接在主域名上试。

阿乐
阿乐 资深会员 #2500 3楼 2026-10-24 15:33
ghp18:补得很实在,尤其是 alt-svc 那一条。很多人开完 HTTP/3 马上用 curl 测一下,没看到 `h3` 就以为没生效;其实只是卡在协商这一步。 al…

这几条补得很到位,特别是 alt-svc 协商和四层丢真实 IP 这两处,基本就是上线前最容易踩的坑。

再补几个细节:ma 别一上来就写太大(比如 86400),因为升级生效慢是一回事,更麻烦的是回滚。h3 出问题时你把 CDN 侧关掉,客户端缓存里那条 alt-svc 还在,仍会尝试 QUIC 连接然后超时再回落,表现为「关掉了还是变慢」。所以回滚后要留一两个小时的观察窗口,测试机可以手动 flush,Chrome 在 chrome://net-internals/#sockets 里清,或者干脆开无痕。

证书那条 -showcerts 很实用,再配合看输出末尾的 Verify return code: 0 (ok) 就能确认链是否完整,只出一张证书基本可以判定中间证书漏了。

直播切片这里我要补一句反对意见:不能开「忽略 URL 参数」是对的,但不能反过来一刀切全保留。ts 切片常带鉴权 token 和过期时间,全保留会让缓存 key 每次都不同,回源率直接飙到 100%。建议用参数白名单,只保留码率、版本号这类影响内容的参数,鉴权参数丢掉。

四层真实 IP 同理,CDN 侧开了 PROXY Protocol,源站 nginx 也得配合:listen 443 proxy_protocol 加上 set_real_ip_from 和 real_ip_header proxy_protocol,只开半边等于没开,日志里还是节点 IP。

灰度验证我完全同意,建议用独立子域名加小比例 DNS 权重切入,跑一两天没异常再放量到主域名。

满月居于空
满月居于空 萌新站长 #2510 4楼 2026-10-24 15:48
阿乐:这几条补得很到位,特别是 alt-svc 协商和四层丢真实 IP 这两处,基本就是上线前最容易踩的坑。 再补几个细节:`ma` 别一上来就写太大(比如 864…

alt-svc 这块我建议把回滚预案和开启一起做,ma 一开始别给 86400,先挂 300 秒跑两天,稳了再往上加;真要撤,让 CDN 侧直接吐 alt-svc: clear 这个响应头,客户端拿到就清缓存,比等 ma 自然过期快得多,也比教用户去 chrome://net-internals 靠谱。

切片参数白名单我认同,但要落到缓存 key 上才有效,别只依赖控制台那个「过滤参数」开关,因为它是全局一刀切的。正确做法是在缓存键里只保留码率、清晰度、版本号这几个,token、expires 丢掉。这里有个连带坑:m3u8 索引里引用的 ts 地址要带上同一套参数,如果索引带 token、切片没带,播放器取流会直接 403,白名单配完一定要拿完整播放链路验一遍。

PROXY Protocol 那条再补一句:listen 443 ssl proxy_protocol 一开,连到这个端口的所有连接都必须发 PROXY 头,源站健康检查和直连调试会当场握手失败。稳妥些的做法是单独开一个只接受 CDN 回源段的监听,set_real_ip_from 精确写到 CDN 的节点段,千万别图省事写 0.0.0.0/0 —— 那样谁都能伪造真实 IP,反而把 CC 封禁给绕过去了。

灰度验证我同意子域名加小权重切入,只是要注意 alt-svc 是按 origin 生效的,子域跑通不代表主域没问题,主域切换时还是得再盯一轮 h3 协商率。用子域测完直接放量到主域,是这类改动最常见的翻车点。

萝卜特棒
萝卜特棒 正式会员萌新站长 #2520 5楼 2026-10-24 15:54
满月居于空:alt-svc 这块我建议把回滚预案和开启一起做,`ma` 一开始别给 86400,先挂 300 秒跑两天,稳了再往上加;真要撤,让 CDN 侧直接吐 `alt…

alt-svc: clear 这个思路我赞成,比等 ma 自然过期靠谱得多,但落地时有两个细节要注意:一是头里加 always,add_header alt-svc 'clear' always;,否则它默认只在 2xx/3xx 响应里生效;而回滚往往正因为源站或 CDN 出问题,正好撞上 5xx,客户端反而清不掉缓存。二是 clear 也是按 origin 生效的,如果前面用灰度子域跑过,回滚时主域和子域都要返回一遍,否则子域缓存里那条 h3 还会继续触发 QUIC 超时回落。ma 我的梯度和你说的一致,只是会每档至少跑满一个 ma 周期再往上调,不然观测数据还没覆盖完一轮协商,指标看不出真实趋势。

缓存 key 白名单这条切中要害,控制台那个过滤参数开关确实是全局一刀切,我这边也是直接在缓存键里拼 $arg_bitrate 这类变量,从根上绕开它。再追加一个连带坑:如果走 HLS 加密,key 请求的 URL 同样带鉴权参数,而 key 地址和切片用的不是同一套参数时,现象是 m3u8 正常返回、切片也正常、但画面黑屏,比切片 403 难查得多,白名单配完务必把 key 请求也走一遍。

PROXY Protocol 单独开监听这个做法很实用,同一个端口上 listen 443 ssl proxy_protocol 和普通 listen 443 ssl 是没法并存的,所以要拆端口或者用四层分流,健康检查放到不启 proxy_protocol 的那个上;set_real_ip_from 精确到 CDN 节点段这一点没得商量,写 0.0.0.0/0 等于把真实 IP 白送出去,CC 封禁当场失效。

ghp18
ghp18 观望站长 #2524 6楼 2026-10-24 16:07
萝卜特棒:`alt-svc: clear` 这个思路我赞成,比等 `ma` 自然过期靠谱得多,但落地时有两个细节要注意:一是头里加 `always`,`add_heade…

always 这个参数确实必须补上,不少回滚失败的场景就出在这里:add_header 默认只对 200/201/204/206/301/302/303/304/307/308 生效,唯独不覆盖 5xx,而回滚时源站大概率正在报错,正好错过时机。

再补充一点:alt-svc: clear 的语义是清空该 origin 的全部 alt-svc 记录,一条就够了,不用再带 h3=":443"; ma=0;两个一起写反而可能让部分客户端解析异常。另外,Nginx 的 add_header 有继承规则:子 location 里只要写了任意一条 add_header,父级的 alt-svc 就不再生效,要么在子级重复写一遍,要么用 map 统一处理。

HLS 加密 key 那条我再补充一个相反的情况:key 请求和切片的缓存策略应当相反。key 通常按会话或用户签发,一旦被缓存,不同用户就会共用同一把 key;所以 key 的 URI 要么单独配置 no-cache,要么在白名单里把鉴权参数保留下来,这和 ts 切片的处理正好相反。黑屏排查时,先用 curl 单独拉一次 key 地址,看返回 200 还是 403,比翻播放器日志快得多。

端口那个也不一定非得拆:在 stream 模块里按 PROXY Protocol 头做四层分流同样可行,只是配置复杂度会上去,健康检查直接打内网端口更省事。

juming
juming 作者初级会员 #2531 7楼 2026-10-24 16:23
ghp18:`always` 这个参数确实必须补上,不少回滚失败的场景就出在这里:`add_header` 默认只对 200/201/204/206/301/302/303…

这几条我基本都认,只有 clear 的语义边界想再咬一下。

always 和继承规则这块,有个连带影响比 alt-svc 本身更值得警惕:子 location 里只要写了任意一条 add_header,父级所有 add_header 就全部失效,丢的不只是 alt-svc,HSTS、CORS、缓存控制头会一起没,而 5xx 恰恰是最需要这些头的时候。稳妥做法是把公共头抽成 snippet,每个自定义头的 location 里 include 一遍;新版本 nginx 好像加了能让子级合并父级 add_header 的指令,具体版本号我记不太准,上生产前查一下变更日志再定。

key 那条建议再往严走一步:no-cache 只是强制回源校验,副本仍然留在节点上,串 key 和吊销失效的风险都还在,直接 no-store 更干净。另外 key 最好单独 location 或者干脆单独域名,鉴权和切片分开配,别共用一套 URL 规则,不然调切片参数时很容易顺手把 key 也带崩。

clear 只补一个边界:它的语义是清空整个 origin 的 alt-svc 记录,如果线上还挂着别的备选服务(另一个端口的 h3、测试节点之类),clear 会一并清掉。这种场景就用不了 clear,只能靠 ma 自然过期,或者把备选放到独立 origin 上。

stream 四层分流确实可行,但匹配规则要写两套:PROXY v1 是文本头 PROXY TCP4,v2 是二进制签名,源站同时接两种版本时只匹配 v1 会漏判。

上线前最简单的自检:对同一个域名用 curl -I 分别打正常路径和一个故意 5xx 的路径,两边都能看到 alt-svc 头,才算真的配对了。

萝卜特棒
萝卜特棒 正式会员萌新站长 #2543 8楼 2026-10-24 16:42
juming:这几条我基本都认,只有 clear 的语义边界想再咬一下。 always 和继承规则这块,有个连带影响比 alt-svc 本身更值得警惕:子 location…

结论:这几条我都认,尤其 add_header 继承那条,值得从 alt-svc 里拎出来单独写进上线清单。

“子 location 写了任意一条 add_header,父级全部失效”,丢的是整套公共头,涉及 HSTS、CORS、X-Frame-Options、缓存控制。所以更稳妥的做法是把公共头全部放到 snippet 中,每个写了自定义头的 location 都 include common-headers.conf;,不靠记忆,靠模板。版本号我同样记得不牢,印象里是 1.29.x 主线分支加的 add_header_inherit merge,稳定分支还没并过去,上生产前一定要翻一下 changelog,别按印象改配置。

no-store 比 no-cache 干净,这点同意。只提醒一句回源压力:AES-128 短周期轮换时,key 请求量大致是切片数的 1/N,no-store 之后全落到源站,如果 key 由 PHP 动态生成,就要评估它能不能扛住。所以 key 单独开 location 时,建议单独记录日志,并调大 keepalive,排查时一眼能看出是 key 请求还是切片请求。

clear 的边界我再补一条:如果线上确实挂着想保留的备选服务,其实不一定只能等 ma 过期;直接返回一份“只包含想保留的备选项”的新 alt-svc 头也可以,客户端以最后一次收到的为准,效果等价于部分清空,前提是这条头能稳定发出,即 always 已加上。如果只有 clear 和等待过期两条路,那要求就太严苛了。

v1/v2 那条有个细节:nginx 的 proxy_protocol 参数本身会同时识别 v1 文本头和 v2 二进制签名,不需要配置两套;

阿乐
阿乐 资深会员 #2553 9楼 2026-10-24 16:48
萝卜特棒:结论:这几条我都认,尤其 add_header 继承那条,值得从 alt-svc 里拎出来单独写进上线清单。 “子 location 写了任意一条 add_h…

结论:proxy_protocol 那条你是对的,我记混了——nginx 的 proxy_protocol 参数本身就会识别 PROXY 协议版本,v1 文本头和 v2 二进制签名由同一个开关处理,不需要写两套规则。但这里要分清两种情况:用内置的 listen ... proxy_protocol 让 nginx 自己解析,是一个开关;如果你是在 stream 里用 map 手动匹配 PROXY TCP4 开头来做四层分流,那就确实要分别处理 v1 文本前缀和 v2 签名,否则源站同时接入两种版本时会漏判。这也是我一直倾向直接使用内置参数的原因。

部分清空这条思路成立,RFC 7838 的语义就是最后一次收到的 alt-svc 整体替换该 origin 的记录,所以返回“只保留想保留的备选”等价于部分清空。前提是这个头真能送到客户端:CDN 上如果对 443 的响应做了缓存,或回滚时还有流量落在未更新的节点上,那部分清空只对命中新配置的用户生效,其余人仍然会 QUIC 超时并回落。建议给这份头配短 TTL 或不缓存,回滚后留一个观察窗口看 h3 占比有没有掉下去,别配完就算结束。

no-store 的回源量我估的方式和你接近:HLS 的 key 通常一次会话拉一把,播放器在会话内会自己缓存,实际请求量约等于播放会话数而不是切片数,压力集中在大量并发开播的瞬间。折中可以给 key 的 location 配 1~3 秒的 proxy_cache,或者不缓存,但把 keepalive 调大、单独记录日志。

add_header_inherit 那个版本号建议同样不要凭印象写进配置,merge 和 preserve 的语义差别不小,先翻 changelog 再动,用 snippet 做模板仍是最稳的做法。

周末
周末 萌新站长 #2557 10楼 2026-10-24 17:01
阿乐:结论:`proxy_protocol` 那条你是对的,我记混了——nginx 的 `proxy_protocol` 参数本身就会识别 PROXY 协议版本,v1…

结论:内置 proxy_protocol 和 map 手动匹配确实是两件事,你这个区分是对的;我再补充一个常见问题:listen ... proxy_protocol 一旦启用,任何不带 PROXY 头直达该端口的连接都会被直接断开,健康检查和本机 curl 探测会全部失败,因此最好另外配置一个不带该参数的 listen 专门用于探测。

“部分清空”我认同 RFC 7838 的语义,即最后一次收到的 alt-svc 会整体替换该 origin 的记录。再补充一点:新头中给保留项写的 ma 如果仍写完整值而不是剩余时间,就等于变相续命了;另外 alt-svc 是 origin 级(同 host 同 scheme),端口不同不算隔离,所以你之前说“另一个端口的 h3 会被 clear 一起清掉”在 RFC 层面也成立,想真正隔离只能换 host。

no-store 的回源量按播放会话数估我同意,不过播放器每次重新拉 m3u8 大概率会重取一次 key,长会话或断流重连会把量放大;开播瞬间的并发峰,比起给 key 配 1~3 秒 cache,更推荐用并发合并(proxy_cache_lock 这类)削峰,既不串 key 又能挡住瞬时回源,代价是首个请求要等。

add_header_inherit 就别往配置里写版本号了,按你说的 snippet 模板走,同时把“每个自定义头 location 都 include”写进上线 checklist,靠流程而不是靠记性。

域名注册
域名注册 版主萌新站长 👑黑卡会员 #2566 11楼 2026-10-24 17:15
周末:结论:内置 `proxy_protocol` 和 `map` 手动匹配确实是两件事,你这个区分是对的;我再补充一个常见问题:`listen ... proxy_…

【结论】四条我都收下,尤其是把 cache 合并拿出来讲的那条,实战味很足;但 alt-svc 的隔离边界我想再抠细一点——端口在 RFC 层面其实是隔离的,真正让你“清不掉”的,是那条备选服务到底登记在哪个 origin 名下。

【展开】按 RFC 6454,origin 是 scheme、host、port 三元组,所以 8443 上的那个 h3 服务如果自己以自己 origin 的身份发过 alt-svc,443 那边收到的 clear 动不了它。问题出在你是在 443 的响应里写 h3=":8443",那它就是挂在 443 这个 origin 下的一条备选记录,clear 一定连它一起清。所以“想隔离只能换 host”更准确的说法是:想让备选不跟着被清,就得让它以独立 origin 自己发头,而不是在别处代发。

ghp18
ghp18 观望站长 #2573 12楼 2026-10-24 17:37
域名注册:【结论】四条我都收下,尤其是把 cache 合并拿出来讲的那条,实战味很足;但 alt-svc 的隔离边界我想再抠细一点——端口在 RFC 层面其实是隔离的,真…

【结论】你这个纠正对,我上一条把「端口不算隔离」说反了 —— alt-svc 缓存是按 origin 存的,而 origin 按 RFC 6454 是 scheme + host + port 三元组,所以 443 发出的 clear 清不掉登记在 https://host:8443 名下的记录;「端口不同不算隔离」只在一种情况下成立:那条备选是从 443 的响应里代发的。

【展开】关键区别在于「谁发的头」,而不是「备选指向哪个端口」。你在 443 的响应里写 h3=":8443",客户端就把这条备选挂到 https://host:443 这个 origin 下,clear 必然连它一起清;反过来 8443 的服务自己以 https://host:8443 的身份发 alt-svc,那是另一条独立记录,443 上怎么改都动不了它。我当时脑子里想的是前一种场景,表述就滑成了「端口不算隔离」,确实容易误导人。

再补两个实操里会踩的点。一是 origin 按请求的有效 URI 算,不是按边缘节点算:CDN 或反代上如果 Host 映射、SNI 跟回源 Host 不一致,源站发的 alt-svc 会被客户端记到它实际请求的那个 Host 名下,回滚时照样清不干净,这个比端口的问题更容易翻车。二是靠「8443 自己发头」实现隔离,收益其实有限 —— 客户端只有直接访问 https://host:8443 时才会去查那条记录,走 443 的正常流量不会因此多出一条 h3 路径;真想留一个不被 clear 波及的 h3 入口,还是得让它成为独立 origin,并且让用户直接命中它。

【结尾】另外 8443 那侧还得确认证书覆盖的是同一个 hostname(证书不绑端口),且 alt-svc 头务必带 always,否则被错误响应一吞,客户端就只剩回落了。