接口调不通别先怪后端:curl 在服务器上排错的 6 个姿势
新服务上线、第三方接口接不通,第一反应往往是"后端挂了"或者"网络有问题"。其实十次有八次,问题出在自己这台服务器上——DNS、证书、超时、代理,任何一个环节都能让请求悄无声息地失败。curl 是每台 Linux 服务器自带的瑞士军刀,下面 6 个姿势,基本能覆盖日常排错的九成场景。
1. 先加 -v:让请求"开口说话"
不加参数的 curl 失败时只给一句话,信息太少。排错第一步永远是 -v(verbose),看完整的请求头、TLS 握手和响应头:
curl -v https://api.example.com/health
重点看三行:Trying 1.2.3.4...(DNS 解析出的 IP 对不对)、SSL connection using TLSv1.3(握手走到哪一步)、< HTTP/1.1 200(服务器到底回了什么)。如果卡在 Trying 不动,是 DNS 或出站网络问题;如果握手阶段报错,往证书方向查。
2. 超时要分开设:连接超时与总超时不是一回事
接口偶尔慢一次就把脚本拖死,常见原因是没设超时。curl 有两个超时参数,分工不同:
curl --connect-timeout 5 --max-time 15 https://api.example.com/data
--connect-timeout 只管"连上服务器要多久",5 秒连不上就放弃;--max-time 是整个请求的总时限,15 秒内没拿到完整响应就中断。只设一个 --max-time 30 秒,遇到 TCP 握手 hang 住的情况照样会傻等;两个都设,才是稳妥的写法。写定时任务里调接口的脚本时,这两个参数必须有。
3. 证书报错先别加 -k:先确认错在哪
自签证书、证书过期、中间证书缺失,curl 都会报 SSL certificate problem。很多人顺手加 -k(跳过验证)就过去了,开发环境可以,生产环境等于把门打开了。正确做法是先看清报错,再决定:
# 看证书链与有效期,先定位问题
curl -v https://api.example.com/ 2>&1 | grep -E "subject|issuer|expire"
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -dates -issuer
如果是证书过期,联系对方续期;如果是自签证书或内网 CA,把 CA 证书传到服务器,用 --cacert 指定:
curl --cacert /etc/ssl/certs/internal-ca.crt https://api.example.com/
只有确认是测试环境、且明确知道风险时,才临时用 -k。
4. 域名解析不对:用 --resolve 绕过 DNS 验证
接口时通时不通,ping 域名能通但 curl 失败,或者同一域名在不同机器上解析到不同 IP,先怀疑 DNS。直接指定解析结果,绕过 DNS 验证:
# 不走 DNS,直接连指定 IP,同时保留正确的 Host 与 SNI
curl --resolve api.example.com:443:1.2.3.4 https://api.example.com/health
如果加了 --resolve 就通了,说明问题在 DNS:查 /etc/resolv.conf 用的哪台 DNS,再用 dig api.example.com 对比两台 DNS 的返回。国内服务器常见的坑是默认 DNS 被污染或响应慢,换成 223.5.5.5 或 114.114.114.114 往往就好了。
5. 测接口快慢:-w 输出耗时分段
接口慢,先别猜。用 -w 把一次请求拆成 DNS、建连、TLS、首字节、总耗时五个数字,慢在哪一段一目了然:
curl -o /dev/null -s -w "dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://api.example.com/data
典型读法:dns 大是 DNS 慢;connect 大是网络或服务器负载问题;ttfb 大是后端处理慢;total 接近 ttfb 说明传输本身没问题。把这条命令存下来,下次接口慢直接跑一遍,比凭感觉猜快得多。
6. POST 调试:-d 与 -H 一次写对
调 POST 接口最常见的两个坑:一是没加 Content-Type,二是 JSON 里的引号被 shell 吃掉。标准写法:
curl -X POST https://api.example.com/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test123"}'
单引号包住整个 JSON,双引号留在 JSON 内部,shell 就不会误解析。如果 JSON 很长,写进文件再用 --data @body.json 传,更稳。需要看服务器原样返回时加 -i,响应头和 body 一起打印,状态码、Content-Type 都在眼前。
一个排错顺序
接口不通时,按这个顺序查,基本不会走弯路:-v 看走到哪一步 → 超时分开设、确认不是 hang 住 → 证书问题先查过期与链 → --resolve 排除 DNS → -w 分段测耗时定位慢的环节 → POST 检查请求头与 body 格式。
curl 不需要装任何东西,服务器上一定有。把这 6 个姿势记熟,下次接口调不通,先在自己这台机器上跑一遍,再去找后端——大概率问题在出门之前就解决了。
- 点赞
- 收藏
- 关注作者
评论(0)