代理IP链路里”突然卡一下又恢复”的抖动,并不一定来自代理出口本身——很多时候是 TCP 自带的”拥塞标记”机制在链路中间被丢掉了。显式拥塞通知 ECN 把”丢包猜拥塞”换成”标记告警”,但在代理IP形成的两段连接上协商和透传各做一次,中间任何一跳不识别或干脆不转发,这个机制就名存实亡。把这条链路看明白,抖动溯源才不绕远。
ECN 到底想替代什么
传统 TCP 用”丢包当作拥塞信号”——发现包没回来就降速。这种方式简单粗暴,但代价是把少数拥塞信号变成大量重传。ECN 换了一种思路:在 IP 头打 ECT 标记表示”我可以接收拥塞通知”,中间路由队列接近满时把 ECT 改成 CE 标记,接收方用 TCP 头 ECE 位告诉发送方,发送方用 CWR 位确认——拥塞信号不再以丢包形式出现,链路体验顺一些。
把这条信号在代理IP链路上展开看,它经历了三次传递:
客户端 → 代理IP出口:本机 SYN 握手里会带 ECT 与 ECE/CWR 选项协商;出口侧代理软件按规则决定是否在自身回复里也保持协商通过。这一段如果出口软件是全协议透传的模式,ECN 协商基本能保真。
代理IP出口 → 目标站:代理IP用自己的 TCP 连接到目标站,第二次握手在目标站侧再协商一次 ECN。这次协商成功,ECN 才真正进入目标站的队列调度视野里。
CE 标记如何回到发送方:中间路由在 IP 头盖 CE 标记,目标站收包后把 ECE 置位回告。问题就出在代理IP这一跳——它需要把”目标站回的 ECE 消息”映射回”与客户端那段连接”的 ECE 字段,握手时协商不一致或中间隧道的 IP 头被重写,CE 标记经常在中途被吞掉。
| 链路形态 | ECN 协商 | CE 标记透传 | 典型表现 |
|---|---|---|---|
| 直连 | 两端协商成功 | 基本完整 | 抖动少,丢包式降速为主 |
| 走代理IP(两段都支持ECN) | 两段各自成功 | 依赖代理软件透传策略 | 接近直连,偶尔被中间设备吞掉 |
| 链路中间某段不识别ECN | 目标站侧不接收 | CE 标记被吞 | 降速仍走丢包路径,ECN 形同虚设 |
怎么判断 ECN 是不是在干活
最直接的办法是抓 SYN 包看选项字段:客户端发起的 SYN 里 ECN-Echo 和 CWR 两个位是否同时置位,代理回复的 SYN+ACK 里 ECE 位是否回应。再到目标站那段抓包核对一次,两边都通过协商才叫链路 ECN 真正可用。Linux 下 sysctl 里 net.ipv4.tcp_ecn 也有 0/1/2 三个档可对照(关、被动、主动),便于排查本机协商策略。
如果业务对延迟敏感、又经常发现抖动,可以试着把代理IP出口的网络层设备换成支持 ECN 透传的型号,或者选链路中转跳数少、隧道封装少的服务商——少一层封装少一次 ECN 丢失。代理IP解决的是”出口可控”,但 ECN 能否真正发挥作用还要看代理前后两条链路本身的完整度。
