排错流程
按现象分类的系统排查路径,从连不上、IP 不对、速度慢到被目标站封。
按现象找到对应的小节,照顺序往下走。每一步都是能独立验证的,不要跳步——跳步的结果通常是改了三个地方然后不知道哪个起了作用。
通用第一步:最小化复现
不管什么现象,先用最短的 curl 命令确认基线。这一步能排除掉一半的问题(客户端库配置、连接池、代码逻辑)。
# 1. 不带任何参数
curl -v -x 'http://USERNAME:PASSWORD@GATEWAY_HOST:58971' https://api.ipify.org
# 2. 通了再加国家
curl -v -x 'http://USERNAME-country-US:PASSWORD@GATEWAY_HOST:58971' https://api.ipify.org
# 3. 通了再加你实际用的全部参数
curl -v -x 'http://USERNAME-country-US-state-California-city-Los%20Angeles-session-t1-time-30:PASSWORD@GATEWAY_HOST:58971' https://api.ipify.org
完全连不上
拿到 407
先看 X-NextProxy-Error:proxy_auth_required 表示缺少或无法解析认证,invalid_credentials 表示账号或密码不匹配。后者请从控制台复制原始文本,核对大小写以及 I、l、1,不要从截图重新识别。
确认客户端真的发出了认证头
curl -v -x 'http://USERNAME:PASSWORD@GATEWAY_HOST:58971' https://api.ipify.org 2>&1 | grep -i proxy-auth
应该看到 > Proxy-Authorization: Basic ...。没看到就是客户端配置方式不对。
各语言的常见坑:Java 要设 jdk.http.auth.tunneling.disabledSchemes="";axios 要写 proxy: false;Puppeteer 要用 page.authenticate()。见对应的接入示例。
确认 shell 没有吃掉凭据
密码里的 $、!、& 在双引号或无引号时会被 shell 展开。用单引号。
# 危险
curl -x "http://user:p@ss!word@host:58971" ...
# 安全
curl -x 'http://user:p@ss!word@host:58971' ...
确认没有重复的认证头
客户端配置里同时设了代理 URL 的 userinfo 和额外的头,会发出两个 Proxy-Authorization,网关拒绝。
拿到 400
invalid_proxy_parameters 表示用户名参数格式、顺序、范围或依赖错误。去掉所有参数,只用基础账号测试,通了再逐项加回;核对 用户名参数完整参考。invalid_request 则检查请求和目标地址格式。
拿到 403
按 X-NextProxy-Error 分开排查:
account_disabled/account_expired:控制台确认账号状态和到期时间。access_denied:检查账号权限、来源绑定及端口认证模式;免密端口不能再发送账号密码。target_denied:换一个允许的公网目标测试,检查 目标地址限制。
先有 200 Connection Established、随后目标站返回的 403 属于目标站拒绝,不能据此认定代理密码错误。
拿到 402
traffic_exhausted 查用户共享流量池;account_quota_exhausted 查子账号上限减已用量;quota_exhausted 查可用配额。子账号设了独立上限时,流量池还有量也可能被拒。额度不足不能靠重复连接解决,见 代理子账号。
拿到 429
connection_limit 表示账号并发或建连频率达到限制。降低并发、复用合适的连接并退避;不要立即大量重连。协议识别前的来源 IP / 全局保护可能直接断开,见 限额与配额。
拿到 502、503 或 504
502 upstream_connection_failed:出口连接或握手失败。503 service_unavailable:没有满足条件的可用代理 IP,或服务暂不可用。504 upstream_timeout:建立代理连接超时。
对 503 逐个去掉 city、state、country,并从控制台目录复制准确地区值,见 地域定位。粘性会话不可用时可以换新的 session 值建立新会话;新会话可能使用不同的出口 IP。
对可安全重放的请求,最多退避重试 3 次。仍失败时提供发生时间、入口、机器码和脱敏日志,运营可据此定位。出口连接过程中的认证或策略错误会返回网关 502,无需因此修改正确的代理账号密码。
连接直接断掉,没有任何响应
这发生在协议识别之前,来不及构造 HTTP 响应:
- 全局连接数或来源 IP 并发达到上限
- 新连接速率超限(单 IP 1,000/秒)
- 首字节等待超过 5 秒
- 网关资源达到高水位
怎么处理:降低并发和连接建立速率。注意网关资源紧张时只拒新连接,已有连接继续正常——所以"老任务好的、新任务连不上"就是这个原因。
出口 IP 不对
IP 完全没变(和直连一样)
echo "直连: $(curl -s https://api.ipify.org)"
echo "代理: $(curl -sS -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' https://api.ipify.org)"
两个一样说明代理根本没生效:
| 可能原因 | 怎么查 |
|---|---|
NO_PROXY / no_proxy 环境变量排除了目标域名 | echo $NO_PROXY |
| 代码里代理配置没生效 | axios 忘了 proxy: false;Node 原生 fetch 没设 dispatcher |
proxies 的 value 写了 https:// | 网关没有 TLS 入站,value 必须是 http:// |
归属地不是我要的国家
curl -sS -x 'http://USER-country-DE:PASS@GATEWAY_HOST:58971' https://ipinfo.io/json
country 不等于 DE 的话:
- 确认参数是两位大写 ——
de会被拒(400 invalid_proxy_parameters)而不是当成DE - 如果拿到的是
200但国家不对,换一个归属库交叉验证——第三方库之间本身有差异
城市对不上
该固定的 IP 在变
| 原因 | 怎么查 |
|---|---|
time 到期了 | 检查会话时长是否覆盖整个流程 |
session 值大小写不一致 | Job1 和 job1 是两个会话 |
| 原出口 IP 已不可用 | 粘性会话无法恢复已不可用的出口 IP |
| 硬要求 IP 恒定 | 应该用静态住宅,不是粘性会话 |
该变的 IP 不变
# curl 每次调用都是新进程新连接,这样会换 IP
for _ in 1 2 3; do
curl -sS -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' https://api.ipify.org; echo
done
如果 curl 能换但你的代码不能,几乎一定是连接被复用了。轮换需要两个条件:
- 不带
session参数 - 建立新连接
第二个是最常被漏掉的。各语言的做法见 粘性会话与轮换。
速度慢
先分清是哪一段慢
curl -s -o /dev/null \
-x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' \
-w 'dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' \
https://example.com
| 慢的字段 | 含义 | 怎么办 |
|---|---|---|
time_namelookup | 解析网关域名慢 | 你本地的 DNS 问题,跟代理无关 |
time_connect | 你到网关这一段 | 换更近的网关节点 |
time_appconnect | TLS 握手(出口到目标站) | 换地区试试;或目标站本身慢 |
time_starttransfer | 目标站生成响应 | 目标站的事 |
吞吐上不去
确认不是被公平使用机制压了
网关负载 ≥85% 时单账号并发会收紧到 5,000。低负载时能放宽到更高。压测结果不代表高峰能力。
确认开了压缩
curl -H 'Accept-Encoding: gzip, deflate, br' ...
不开压缩不仅慢,还多花 3–5 倍流量。见 流量计费口径。
确认在复用连接
每个新 HTTPS 连接有 3–6 KB 的 TLS 握手开销和一个 RTT。密集请求时不复用连接的代价很大。
这跟轮换 IP 是矛盾的——需要权衡。折中方案是用粘性会话在同一 IP 下复用连接。
如果是大流量任务,换产品线
连接中途断开
| 现象 | 原因 |
|---|---|
| 恰好 5 分钟后断 | 空闲超时。有数据流动就不会断;长轮询/SSE 要加心跳 |
| 恰好 24 小时后断 | 单连接最长生命周期 |
ECONNRESET 频发 | 客户端连接池的 keepAlive 超过网关的 5 分钟空闲超时,用到了已关闭的连接 |
| 随机断开 | 出口连接抖动;带 session 时原会话的出口可能已不可用 |
被目标站识别或封禁
这一类问题不在网关侧,但很常见,所以列一下判断路径。
确认不是 IP 属性问题
用数据中心代理访问对机房 IP 敏感的站点(电商、社媒、票务),换更多数据中心 IP 没用——主流风控能通过 ASN 判断 IP 归属类型。
确认指纹和地区一致
出口 IP 在美国但浏览器报 Asia/Shanghai 时区、zh-CN 语言,这个矛盾本身就是强信号。
指定 country 时同步对齐 locale、timezone_id、地理位置。见 浏览器与指纹浏览器。
确认 WebRTC 没泄露
WebRTC 能绕过 HTTP 代理暴露真实 IP。而且这个网关不支持 UDP,所以 WebRTC 媒体流本来就走不通——设成"真实"会直接泄露。
必须设为"替换为代理 IP"或"禁用"。
确认行为模式不异常
固定间隔的请求、完全一致的 User-Agent、没有鼠标移动的表单提交,这些都是行为层面的信号。IP 换得再勤也补不上。
账号类任务改用静态 IP
目标站把 IP 变动当风险信号。账号养护、社媒运营应该用静态住宅——固定 IP 30 天,比粘性会话的 120 分钟上限可靠得多。
还是解决不了
带上这些信息开工单(POST /api/v1/support/tickets):
- 完整的
curl -v输出(把凭据涂掉) - 你用的完整用户名参数(涂掉基础用户名部分)
- 网关节点地址和端口
- 收到的准确状态码或 SOCKS5 reply 码
- 失败的时间范围(带时区)
- 失败率:是 100% 还是间歇性的
- 已经排除了哪些可能