API 报了 connection refused 或者连接超时?按这五层往下敲,哪层断了就只查哪层

先把答案给你

connection refused 是对方把门关了,而且明确告诉你门关了——你的包到了那台机器,机器回了一个 RST。connection timed out 是敲门没人应——包发出去了,一个字节的回应都没有,一直耗到你设的上限。前者说明有台机器活着,只是那个端口上没有服务在听;后者说明你连那台机器活没活着都不知道,包可能被防火墙丢了,也可能被中间设备静默吞掉。

排查路径只有一条,自上而下五层:

  1. 域名解析:这个域名现在解析成了哪个 IP
  2. TCP 连通性:那个 IP 的那个端口通不通
  3. TLS 握手:证书链能不能建起来
  4. HTTP 应用层:服务端返回什么状态码
  5. 客户端配置:地址、端口、超时、本地代理设置

哪一层先断,就只查那一层。上面一层没通,下面几层跑出来的输出全是噪音。

报错原文已经写清了是第几层

curl 的 (7) 和 (28) 一眼能分

curl: (7) Failed to connect to xyuapi.top port 443 after 21 ms: Couldn't connect to server
curl: (28) Connection timed out after 30001 milliseconds

(7) 后面跟着 21 ms,二十毫秒就失败,说明包到了对端被立刻拒绝。(28) 后面是 30001 milliseconds,一秒不差停在三十秒,那是你设的超时到点了,对端从头到尾没吭声。

Python requests 那两句长报错

requests.exceptions.ConnectionError: HTTPSConnectionPool(host='xyuapi.top', port=443): Max retries exceeded with url: /v1/models (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f2c1a0b3e50>: Failed to establish a new connection: [Errno 111] Connection refused'))

别被长度吓到,只看方括号里那四个词:[Errno 111] Connection refused,等价于 curl 的 (7)。同一句式里换成 Name or service not known,性质就整个变了——域名压根没解析出来。

Node 的两句短报错

Error: connect ECONNREFUSED 127.0.0.1:7890
getaddrinfo ENOTFOUND xyuapi.top

注意前一句里的地址是 127.0.0.1:7890,根本不是你请求的域名。说明有个东西在告诉程序去本机 7890 端口找服务,而 7890 上没有任何程序在听。这是本地代理软件残留的典型长相。后一句 ENOTFOUND 就是解析失败。

socket 超时和 502 性质完全不同

socket.timeout: timed outRead timed outrequests.exceptions.ReadTimeout 都发生在已经连上之后,是读阶段没等到数据。502 Bad Gateway504 Gateway Timeout 更清楚——请求完整到达了应用层,是转发或计算环节出的问题。看到这两个状态码,网络层可以整体排除。

五层逐层敲:每层的命令和判定标准

第①层 DNS:本机解析不对,后面全白做

nslookup xyuapi.top                              # Windows
Resolve-DnsName xyuapi.top -Server 8.8.8.8       # Windows,指定公共 DNS
dig +short xyuapi.top @223.5.5.5                 # Linux
getent hosts xyuapi.top                          # Linux,看本机实际解析

关键动作是横向对比,把四家公共 DNS 的结果排在一起看:

for s in 223.5.5.5 119.29.29.29 8.8.8.8 1.1.1.1; do printf '%s -> ' "$s"; dig +short xyuapi.top @$s | tr '\n' ' '; echo; done

如果本机解析出来的 IP 和权威 DNS 不一致,后面所有排查都是白做的,先解决这个。同一个域名在不同网络解析到不同 IP,原因基本三种:本地 DNS 被改过、路由器做了 DNS 分流、缓存里存着旧记录。它们都会让你的机器指向一台根本没有对应服务的机器,于是你看到拒绝或超时,而真相是域名压根没解析对。

第②层 TCP:拒绝和超时在这一层分开

Test-NetConnection xyuapi.top -Port 443    # Windows,看 TcpTestSucceeded
nc -vz -w 5 xyuapi.top 443                 # Linux
telnet xyuapi.top 443                      # 老机器上的备选

nc 立刻返回 Connection refused,就是拒绝——包到了对端,对端主动回了 RST,通常意味着那个端口上没有服务在监听,或者防火墙配了主动拒绝规则。如果卡到五秒才打印 timed out,那是包被丢弃了:可能防火墙按丢弃规则处理、路由不通、对端主机下线,或者中间设备按策略静默处理。

超时值别设太大。局域网两秒,公网五到十秒。超过十秒还没回应,直接当不通处理。

第③层 TLS:看 Connected to 之后卡在哪

curl -vI https://xyuapi.top/v1/models

-v 会按顺序打印每一步:Trying ...Connected to ...、证书信息、请求行、状态码。停在 Trying 就是 TCP 都没建起来,回上一层查。已经打印 Connected to 却卡在证书那段,问题在 TLS 层——中间设备替换了证书,或者本机系统时间不对导致证书被判定成未生效。时钟偏差超过证书有效区间,握手会直接失败,报出来的却是证书错误。

第④层 HTTP:拿到状态码就别再查网络了

curl -i -s -o /dev/null -w '%{http_code}\n' --max-time 15 https://xyuapi.top/v1/models

只要拿到三位状态码,连接层就完全没问题。401403 是令牌的事,404 是路径写错了,都是应用层问题,别再折腾 DNS 和防火墙。

第⑤层 客户端:八成「接口挂了」卡在这里

五层定位表

层级该敲的命令典型输出结论
① DNSnslookup xyuapi.top返回的 IP 与公共 DNS 不一致本机解析被改或缓存污染,先修这个
② TCPTest-NetConnection xyuapi.top -Port 443TcpTestSucceeded : False端口无人监听或被主动拒绝
② TCPnc -vz -w 5 xyuapi.top 443卡满五秒后 timed out包被丢弃,查链路和出站策略
③ TLScurl -vI https://xyuapi.top/v1/modelsConnected to 却没有证书行握手失败或系统时间不对
④ HTTPcurl -i --max-time 15 https://xyuapi.top/v1/modelsHTTP/1.1 401404连接完全正常,去查令牌和路径
⑤ 客户端核对 base_url、端口、代理环境变量报错里出现 127.0.0.1:7890本地代理残留或地址填错

两种失败在 TCP 层差在哪

RST 是主动拒绝,丢包是没人管

TCP 建连靠三次握手。你发 SYN 出去,对端有三种反应:回 SYN 加 ACK 就是通,回 RST 就是明确不通,什么都不回就是超时。回 RST 的场景是目标端口没有进程在监听、或者中间防火墙配了主动拒绝规则;什么都不回的场景是防火墙按丢弃规则处理、路由黑洞、对端主机下线。

所以拒绝是条有用信息,至少能确定包到达了对端、对端网络是通的。超时的信息量低得多,任何一环出问题都长这个样子。

两种情况的可能性对照

维度connection refusedconnection timed out
返回速度几毫秒到几百毫秒就失败卡满你设的超时上限
TCP 层行为收到对端 RST无响应,SYN 重传若干次后放弃
常见成因端口无服务、防火墙主动拒绝、端口写错、本地代理端口已关防火墙丢弃、路由不可达、IP 被屏蔽、对端宕机
包到没到对端到了未知
下一步动作核对端口与 base_url,查本地代理残留换网络、换入口,用 IPv4 强制对比

超时值设多少才合理

五个高频真因,每个都告诉你改哪里

真因一:本机解析到了错误的 IP

典型现象是同一台机器上浏览器能打开某些站点,命令行却连不上;或者昨天正常今天就全挂。

ipconfig /flushdns                              # Windows 清缓存
ipconfig /renew                                 # 重新获取,让新 DNS 生效
sudo resolvectl flush-caches                    # Linux 清缓存
curl -s -o /dev/null -w '%{http_code}\n' --resolve 'xyuapi.top:443:替换成公共DNS查到的IP' https://xyuapi.top/v1/models

--resolve 就通了,那百分百是本机解析的问题,跟接口无关。这个判断只要十几秒,比反复重启客户端快得多。

真因二:代理软件残留端口

现象固定:报错里出现 ECONNREFUSED 127.0.0.1:7890Failed to connect to 127.0.0.1 port 7890。你根本没在代码里写过代理,是环境变量或系统代理设置里还留着。

要查两个地方,它们互不相通:终端环境变量,和系统代理设置。只清了环境变量、系统代理开关还开着,程序照样会去连那个已经关掉的端口。

set http_proxy                                           # Windows CMD 查看
Get-ChildItem env: | Where-Object Name -match 'proxy'     # PowerShell 查看
$env:http_proxy=$null                                     # PowerShell 清掉
$env:https_proxy=$null
$env:ALL_PROXY=$null
unset http_proxy https_proxy ALL_PROXY                    # Linux 与 macOS

系统代理设置在 Windows 的「设置 → 网络和 Internet → 代理」里,看「使用代理服务器」开关还开着没有,关掉再试。

Python 里还有一层:requests 会自动读这些环境变量,代码层面也要堵住,给会话加一行 session.trust_env = False

真因三:IPv6 优先但出不去

现象是同一个域名 A 机器正常、B 机器卡满整个超时。通常是域名有 AAAA 记录,系统默认优先走 IPv6,而这条路径不通,每次都白等满超时才退化。

curl -4 -s -o /dev/null -w 'v4=%{http_code} t=%{time_total}\n' --max-time 15 https://xyuapi.top/v1/models
curl -6 -s -o /dev/null -w 'v6=%{http_code} t=%{time_total}\n' --max-time 15 https://xyuapi.top/v1/models

-4 通、-6 卡死,结论就定了。修法是在系统里调低 IPv6 优先级,或者在客户端配置里固定用 IPv4。

真因四:客户端超时设置太短

现象是报 Read timed outsocket.timeout,但你手动 curl 同一地址是通的。客户端只给了十到三十秒,而推理模型或长上下文请求要跑更久。改哪里:SDK 初始化时的超时参数、requests 的 timeout=、图形客户端的「高级设置」或「请求超时」输入框。推荐值按上面那三档来。

真因五:防火墙或安全软件拦了出站 443

现象是所有域名都连不上,不只是某一个接口,而且表现是超时而不是拒绝。动作很简单:临时关掉第三方安全软件的网络防护试一次;在公司网络里问一句出口有没有白名单;用手机热点对比一次。热点下能通,就是本地网络策略问题。

一条脚本把五层跑完

存成 check.sh,执行 bash check.sh xyuapi.top,四行结论直接出来。

#!/usr/bin/env bash
HOST="${1:-xyuapi.top}"
PORT=443
URL="https://$HOST/v1/models"

echo "=== 1/4 DNS ==="
PUB=$(dig +short "$HOST" @223.5.5.5 | grep -E '^[0-9.]+$' | head -1)
LOC=$(getent hosts "$HOST" | awk '{print $1}' | head -1)
echo "public=${PUB:-none} local=${LOC:-none}"
if [ -z "$LOC" ]; then
  echo "RESULT: DNS 解析失败,先修 DNS,不要往下查"
  exit 1
elif [ -n "$PUB" ] && [ "$LOC" != "$PUB" ]; then
  echo "RESULT: 本机解析与公共 DNS 不一致,先修 DNS 再往下查"
  exit 1
else
  echo "RESULT: DNS 正常"
fi

echo "=== 2/4 TCP ==="
if nc -z -w 5 "$HOST" "$PORT" 2>/dev/null; then
  echo "RESULT: TCP $PORT 可建连"
else
  ERR=$(nc -v -z -w 5 "$HOST" "$PORT" 2>&1 | tail -1)
  case "$ERR" in
    *refused*) echo "RESULT: TCP 被拒绝 -> 端口无服务、防火墙拒绝、或本地代理端口已关" ;;
    *timed*|"") echo "RESULT: TCP 超时 -> 包被丢弃,查链路与出站策略" ;;
    *)          echo "RESULT: TCP 异常 -> $ERR" ;;
  esac
fi

echo "=== 3/4 TLS ==="
if curl -sS -o /dev/null --max-time 12 "$URL" 2>/dev/null; then
  echo "RESULT: TLS 握手正常"
else
  echo "RESULT: TLS 失败 -> 证书不匹配或系统时间不正确"
fi

echo "=== 4/4 HTTP ==="
CODE=$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 "$URL")
echo "RESULT: HTTP $CODE"
case "$CODE" in
  2*|401|403|404) echo "结论: 连接层完全正常,问题在令牌、路径或参数" ;;
  502|504)        echo "结论: 已到达应用层,上游在报错,稍后重试或换入口" ;;
  000)            echo "结论: 没拿到任何响应,回到第 2、3 步" ;;
esac

输出怎么读

四行 RESULT 就是四层结论:DNS 那行不一致就停下先修;TCP 那行区分拒绝还是超时;TLS 那行失败基本只可能是证书或系统时间;HTTP 那行只要有状态码,连接层就宣告无罪。

Windows 上没有 dignc,用这三条等价命令:

Resolve-DnsName xyuapi.top -Server 8.8.8.8
Test-NetConnection xyuapi.top -Port 443
curl.exe -vI https://xyuapi.top/v1/models

Windows 10 的 1803 版本之后自带 curl.exe。别在 PowerShell 里直接写 curl,那是 Invoke-WebRequest 的别名,参数格式不同,照着 -w 写法会报错。

Python 里把连接失败和读取失败分开

timeout 传元组才分得开两段

timeout=15 是连接和读取共用十五秒,长回答必然被误判成超时。传元组 timeout=(15, 180) 才分得开:前一个数字管连接阶段,后一个管读取阶段。

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

BASE = "https://xyuapi.top/v1"
KEY = "sk-你的令牌"

session = requests.Session()
retry = Retry(total=3, backoff_factor=1.5,
              status_forcelist=[502, 503, 504],
              allowed_methods=["POST"])
session.mount("https://", HTTPAdapter(max_retries=retry))
session.trust_env = False   # 不读代理环境变量,避免残留端口把请求带偏

payload = {"model": "gemini-2.5-pro",
           "messages": [{"role": "user", "content": "你好"}],
           "stream": False}

try:
    r = session.post(f"{BASE}/chat/completions",
                     headers={"Authorization": f"Bearer {KEY}"},
                     json=payload,
                     timeout=(15, 180))
    r.raise_for_status()
    print("OK:", r.json()["choices"][0]["message"]["content"][:40])
except requests.exceptions.ConnectTimeout:
    print("失败在连接阶段:DNS、TCP、TLS 没走通,查前四层")
except requests.exceptions.ReadTimeout:
    print("失败在读取阶段:连上了但服务端太慢,加大读取超时或改流式")
except requests.exceptions.ConnectionError as e:
    msg = str(e)
    if "refused" in msg or "10061" in msg:
        print("连接被拒绝:端口写错、域名解析错、或本地代理端口已关闭")
    elif "Name or service not known" in msg or "getaddrinfo" in msg:
        print("域名解析失败:先修 DNS 再重试")
    else:
        print("其他连接错误:", msg[:200])
except requests.exceptions.HTTPError as e:
    print("已经连上了,是应用层状态码:", e.response.status_code)

重试要放在正确的位置

Retry 只对连接失败和指定状态码生效,业务上的 401 不该重试,重试三次只是白等。status_forcelist 里放 502、503、504 就够了。

症状速查表

你看到的症状结论你现在该做什么
curl: (7) 且几毫秒就失败端口被明确拒绝核对 base_url 与端口,清代理环境变量
curl: (28) 且卡满超时包被丢弃换网络、换入口,试 curl -4
ENOTFOUNDgetaddrinfo域名没解析出来对比 8.8.8.8 的结果,清 DNS 缓存
ECONNREFUSED 127.0.0.1:7890本地代理残留清代理环境变量并关掉系统代理开关
一台机器正常一台卡满超时IPv6 优先但出不去curl -4curl -6 对比后固定 IPv4
Read timed out 但 curl 能通客户端超时太短读取超时提到 120 秒以上
502504请求已到应用层重试,或换备用入口验证
401403404连接毫无问题查令牌与路径,别再查网络了

主入口连不上时,先用备用入口互测

小鱼API(xyuai.cc)是 AI API 接入平台,主入口 https://xyuapi.top/v1,备用入口 https://xyuai.cc/v1,两个入口互为备份。互测的价值不只是多个可用地址,它能把责任范围一次缩小到位:

curl -s -o /dev/null -w 'primary=%{http_code} t=%{time_total}\n' --max-time 15 https://xyuapi.top/v1/models
curl -s -o /dev/null -w 'backup=%{http_code} t=%{time_total}\n' --max-time 15 https://xyuai.cc/v1/models

主入口失败、备用入口正常,说明是你到主入口那条链路的问题,本机网络或 DNS 嫌疑最大;两个入口都失败,更可能是你本地的网络、代理或 DNS 配置有问题,回头查第①②层;两个都通,问题就回到客户端配置和超时上。

接入方式和常用客户端

协议是 OpenAI 兼容的,/v1/chat/completions/v1/models 两个端点,任何支持自定义 OpenAI 地址的客户端都能接。Chatbox、Cherry Studio、NextChat、Cline、RooCode、KiloCode、LobeChat 这些,在自定义地址栏填 https://xyuapi.top/v1 再加令牌就能用,另外也支持 Gemini 原生 /v1beta。填地址注意两点:别带尾部斜杠,也别把 /v1/chat/completions 整个填进 base_url 那一栏。

计费方式

按次计费为主:一次请求固定价,输入长度不影响价格。这点在排查时也有用——上下文从两千字加到两万字,价格一样,不需要为了省钱去压缩提示词。几个价位参考:gemini-2.5-pro 是 0.031 元一次,deepseek-v4-flash-thinking 是 0.05 元一次,claude-opus-4-6-thinking 是 0.25 元一次。另有按量计费和无限卡套餐,最低充值 7 元,支付宝或微信付款,不需要海外信用卡。

下次再遇到,按这三步走

跑一遍五层脚本,看四行 RESULT 落在哪一层;用备用入口互测一次,判断是链路问题还是客户端问题;进客户端核对 base_url、端口和超时三个值。三步做完,绝大多数「接口连不上」都会落到一个具体原因上,而不是停在「好像是网络问题」。

相关阅读

🚀 想要立即使用?来小鱼API体验全系列AI模型

查看全部产品

支持Gemini / Claude / GPT / Grok / DeepSeek · 国内直连 · 支付宝/微信