代理问题在你身处其中时感觉五花八门,但实际上相当重复。几乎所有出错的情况都可以归入八种模式,而在多数情况下,响应本身就会告诉你遇到的是哪一种。这是一份索引:找到你的症状,获取可能的原因和即时解决办法,需要更长版本时再点击链接。
快速对照表
| 症状 | 通常意味着 | 首先该做的事 |
|---|---|---|
407 Proxy Authentication Required | 凭证错误,或用户名中的标志格式有误 | 测试不带任何标志的裸用户名 |
502 Bad Gateway | 当时没有地址匹配你的过滤条件 | 放宽过滤条件 |
509 Bandwidth Limit Exceeded | 套餐额度已用尽,超额未启用 | 检查钱包和套餐 |
| 连接被拒绝或挂起 | 你根本没有连接到网关 | nc -vz p.shifter.io 443 |
| 超时 | 目标响应慢、过滤条件过严,或你自身的并发问题 | 将连接时间与读取时间分开 |
403 或验证挑战页面 | 目标拒绝了身份,而非代理出问题 | 弃用该会话,检查请求头 |
200 但内容错误或为空 | 软性封锁,或地区设置错误 | 校验响应正文,检查地理信号 |
| 每次请求都是同一个 IP | 几乎总是客户端的连接复用问题 | 用独立进程测试 |
407:认证被拒绝
网关拒绝了你的凭证,这说明你的流量已经到达网关,连接本身没有问题。
三个原因几乎涵盖了所有情况:凭证中的拼写错误、扩展用户名中标志格式有误,或者密码在面板中已被重置但某处仍部署着旧的副本。中间这种情况最不容易察觉,因为一个无法识别的值,例如 country-uk 而不是 country-gb,会使整个用户名无法解析,因此被报告为认证失败而非定位错误。
诊断方法始终一致:先去掉所有标志,测试裸用户名。如果成功,问题出在标志上,再逐个加回去测试。如果失败,重新从面板中复制密码。完整细节见修复 407 与凭证错误。
永远不要重试 407 错误。这是终结性的错误,针对它的重试循环会消耗带宽,从外部看起来就像是在进行凭证填充攻击。
502:没有匹配到你的过滤条件
你的凭证被接受了,然后没有地址可用于你请求的组合。这是定位问题,不是故障。
这种情况通常出现在过滤条件非常狭窄时,比如一个小城市、特定的 ASN,或两者的组合,而且在当地资源池较薄弱的时段更容易出现,因为可用性会随人类活动波动。放宽过滤条件,从城市级别退到区域或国家级别,或去掉严格匹配,让网关回退到更大的资源池。如果你是有意依赖严格匹配的,那么这个错误就是系统按预期工作的表现。背景信息见国家可用性。
509:带宽不足
套餐额度已用尽,而超额功能未启用,因此请求停止。连接或配置本身没有任何问题。充值以启用超额,或等待周期重置,如果这种情况经常发生,说明套餐规模不够,这是一个预测问题,详见估算月度带宽。
连接被拒绝,或请求永远挂起
你根本没有与网关建立通信。两个常见原因:你指向的是基于端口的旧版主机而不是 p.shifter.io:443,或者你自己的网络在该端口上屏蔽了出站流量。
在假设代理有问题之前,先测试原始连接性:
nc -vz p.shifter.io 443
如果失败,说明是你这一端的出口或防火墙问题。如果成功但请求仍然失败,那就进入了上面所述的认证流程排查。
超时
这是最模糊的一类,因为多个不同的问题会产生相同的症状。最有用的单一步骤是把连接时间和总时间分开,因为它们指向相反的方向:
curl -o /dev/null -s -w "connect: %{time_connect}s total: %{time_total}s\n" \
-x customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com
连接慢说明问题在代理路径上,或过滤条件过严导致地址选择变慢。连接快但总时间慢说明是目标本身响应慢,这不是更换代理能解决的问题。同时要检查你的超时设置是否只是针对数据中心延迟调优的,因为住宅连接本身就会更慢,两秒的超时会因为并非错误的原因而频繁失败。完整诊断见为什么请求会超时,调优选项见降低延迟。
403、验证码和挑战页面
这些来自目标网站,而不是代理,这说明认证和连接都成功了。目标网站查看了请求并拒绝了它。
即时的应对是弃用该会话,换一个全新的身份,而不是用同一身份重试。持久的应对是找出原因,可能性的顺序依次是速率、请求形态、行为特征,最后才是地址质量。放慢速度比其他任何方法都能解决更多此类问题,参见速率限制与请求节流,如果速率本身是合理的,下一个怀疑对象就是请求头与用户代理之间相互矛盾。恢复方案见当你的 IP 被封禁时该怎么做。
内容不符预期的 200 响应
这是最昂贵的失败,因为表面上一切正常。挑战页面、空结果集、被截断的列表,或一个通用的地区页面,都可能以成功状态码返回,而只统计状态码的流水线会把它们记录为有效数据。
如果内容是错误的而非缺失的,首先要怀疑地理位置问题:与出口国家矛盾的 Accept-Language 请求头,或 DNS 泄露导致主机名从你本地而非代理所在地解析,这两者都会返回看似合理但属于错误市场的内容。参见匹配地理位置、时区和语言设置以及防止 DNS 泄露。
如果内容是挑战页面或占位内容,应将其视为封锁,参见检测被封锁或虚假内容。无论哪种情况,教训都是一样的:在把响应计为成功之前先校验正文,否则你的监控毫无意义。
每次请求都是同一个地址
轮换看起来坏了,但几乎从来不是真的坏了。常见原因是你的 HTTP 客户端在复用一个连接,而出口地址是在建立连接时选定的,而不是按照通过该连接发送的每个请求单独选定的。
先用独立进程测试:
for i in 1 2 3; do
curl -s -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json | head -c 60; echo
done
如果这样能轮换,而你的应用程序不能,原因就是客户端中的连接池。如果两者都不轮换,检查用户名中是否有请求粘性会话的 sid 标志,并确认你看到的地址不是你自己的地址,否则那意味着代理根本没有生效。完整原因见IP 不轮换。
TLS 和证书错误
这类情况较少见,通常与环境有关。可能是过时的 TLS 库拒绝了网关的加密套件,也可能是企业中间设备破坏了信任链。首先更新客户端库。禁用证书验证会让错误消失,但只应用于确认诊断,绝不应用于任何你要发布上线的内容中。
一般的排查顺序
当出现问题而你不确定从哪里开始时:先确认原始连接性,然后测试不带任何标志的裸凭证,再逐个加回标志,最后检查响应是否真的是你所请求的内容,而不是盲目相信状态码。这个流程能在几分钟内定位问题所在的层级,无论症状是错误代码还是看起来微妙有误的数据,流程都是一样的。
对于持续性而非急性的问题,能在你手动注意到之前就捕捉到这些情况的监控方法,见大规模监控代理健康状况。
结论
八种模式几乎涵盖了所有情况。407 是凭证问题或标志格式有误,永远不值得重试。502 是过滤条件为空,而非故障。509 是带宽问题。连接被拒绝意味着你根本没有连接到网关。超时需要先把连接时间和总时间分开,再做其他任何判断。403 或挑战页面是目标网站拒绝了你,所以要更换身份,然后找出原因。内容错误的 200 响应是最危险的一种,这正是为什么正文校验不是可选项。而每次请求都是同一个地址几乎总是你自己客户端的连接复用问题。从连接性开始向外排查,检查实际返回的内容,而不是相信状态码的说法。