为什么 Tor 比 VPN 感觉更慢:点击与下载
Tor 和 VPN 的延迟落在不同工作负载上:先诊断卡住的页面,再怀疑带宽,然后在每次测试中只改一个变量。
下载速率正常、页面却总觉得卡,说明问题出在往返次数而不是带宽。VPN 只多一个加密跳数,Tor 电路却要多好几个,而每个额外跳数都要先完成一次握手,才会有有用的字节流动。这种代价在打开大量短连接的页面上暴露无遗,在单次大文件传输中却几乎消失。一旦看清这个规律,争论就不再是哪件工具更快。
症状指向建立成本,而不是容量
一次页面加载是一串相互依赖的交换:查名字、传输层握手、TLS 握手,然后才是第一个请求。路径上的每一跳都会在绘制任何内容之前,把自己的往返时间插进这条链。大文件下载只付一次同样的建立成本,然后就持续传输——两个工作负载之所以得出不同结论,原因正在这里。
在网络面板里要看第一个字节之前的等待时间,而不是总时间。等待长而内容下载短,指向往返次数;等待短而内容下载长,指向吞吐量。换第二个目标再测一遍,因为一台忙碌中继后面的单个主机证明不了什么。传输正常而点击很慢时,应当远远优先怀疑建立成本,而不是带宽。
延迟和容量以不同方式失效
取两组读数,大部分困惑就自行消解。延迟是每次交换的固定成本,容量是随时间变化的速率,所以同一条路径可以在前者上表现好、在后者上表现差。一台空闲处理器的远端服务器能迅速回答小请求,却仍会把持续传输限制在上行带宽允许的范围内。用户对这种分裂的感受就是:点击很利落,随后进度条几乎不动。
用持续传输测容量,观察速率是保持稳定还是锯齿状。用小请求反复多次测延迟,看的是离散程度而不是最佳样本,因为离散程度大时的体感比平均值更糟。每次改动前后都记下这两个数字,否则事后会把功劳归给错误的变量。
把两者当成一个数字,只会做出永远推不动你所关心指标的修补。延迟抱怨最后被回答成升级带宽,最常见的路径就是这一条。
洋葱路由增加了你没有选择的跳数
Tor 电路通常使用三个中继——一个入口守卫、一个中间节点和一个出口——客户端是从共识里挑选它们,而不是从地图上挑。因此路径可能比直达目标的直线长得多。每个中继还承载别人的流量,所以你的数据流要和该中继剩余的容量共享。
复用电路能缓和这种成本,因为新数据流可以搭上已有电路,而不必再付一次构建费用。每个请求都新建电路的客户端会反复支付建立成本,体感比复用者差得多。出口的选择也很重要,因为有些出口负载更重,而界面上没有任何信息告诉你落到了哪一个。这种共享正是设计的目的,也是延迟无法调成固定值的原因,所以一个慢出口并不足以成为放弃这套安排的理由。
改变链条顺序,就改变了实验
先 VPN 后 Tor 与先 Tor 后 VPN 是两个不同的实验。前一种安排下,VPN 端点承载整条电路,因此你的接入网络只能学到 VPN 地址。后一种安排下,VPN 连接本身走在洋葱路径内部,出口看到的是 VPN 流量。两者都是正当的设计,而把其中任何一种和裸 VPN 相比,测的是另一回事——这也是 Tor 项目关于二者组合的页面把它先当作你想隐藏什么的问题、再当作时序问题的原因。
把设备、接入网络和目标固定下来,两次运行之间只改一个要素。同时挪动服务器、电路和测试主机会产生谁也无法归因的差异。优化之前先写下每种安排对谁隐藏了什么,因为一条暴露了你本想隐藏之物的快速链条,算不上改进。
经得起第二次运行的比较
选两三个你真正在用的目标,在每一个上给同一次交互计时,其中要包含一个拉取大量小资源的页面和一次大传输。在一天中的另一个时段把整套测试重做一遍。
报告的是中位数和最差情况,而不是最快样本,因为交互式工作是按糟糕时刻来评判的。记下客户端、端点或出口,以及那次运行是否复用了电路或隧道。如果某项改动改善了中位数却恶化了尾部,那是取舍而不是胜利;判断用户是否会察觉,才是真正的决定。