调试第三方 HTTP 接口时我常用的几个手段
接外部接口的时候,最容易浪费时间的不是写代码,而是「到底是我的参数错了、 还是对面服务的问题」这个判断。下面几个习惯能把这类判断压缩到几分钟内。
一、先用 curl 把请求固定下来
代码里的请求库会加一堆默认行为:自动重定向、自动解压、自己补 header、
出错时抛自己的异常类型。出问题的时候,这些恰好都在掩盖真相。
先用 curl 打一发最小的、能复现的请求:
curl -sS -X POST 'https://api.example.com/v1/query' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <token>' \
-d '{"q":"test"}' \
-D /tmp/headers.txt \
-o /tmp/body.json \
-w 'code=%{http_code} time=%{time_total}s\n'
把响应头和响应体分开落盘,是很关键的一步:-D 存头,-o 存体,
-w 打印状态码和耗时。这样后面无论要看什么,都不用重新发一次请求。
二、把超时拆成三段来看
只写一个 timeout=10,出问题时你不知道时间花在了哪一步。
curl 的 -w 支持拆开看:
curl -sS -o /dev/null \
-w 'dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total}\n' \
https://api.example.com/health
各段对应的典型问题:
| 指标 | 数值偏大通常意味着 |
|---|---|
time_namelookup | DNS 解析慢或解析器配置有问题 |
time_connect | TCP 握手慢,链路或防火墙问题 |
time_appconnect | TLS 握手慢,证书链或加密套件协商问题 |
time_starttransfer | 服务端处理慢(第一个字节迟迟不来) |
如果 connect 就卡住了,那跟你的请求参数一点关系都没有,
不用再去改 body 了。
三、别只看状态码
很多接口在业务失败时也返回 200,错误信息藏在 body 里; 也有反过来的,返回 4xx 但 body 是正常数据。判断依据要以对接文档为准, 不要默认「非 200 就是失败」。
我会先把原始响应原样存一份,再看解析后的结果。因为一旦经过 JSON 解析,
字段名大小写、数字精度、null 与空字符串的区别都可能被吃掉。
# 完整保留原始字节,不做任何格式化
curl -sS https://api.example.com/v1/data -o /tmp/raw.bin
# 之后再看
file /tmp/raw.bin
head -c 500 /tmp/raw.bin | xxd | head -20
四、编码问题先怀疑,再排查
中文乱码、签名对不上,十有八九是编码或换行符。几个高频点:
- JSON 里的中文被转成了
\uXXXX,肉眼比对时对不上 - Windows 上编辑的配置文件带了
\r\n,参与签名计算时多出两个字节 - 表单参数没做 URL 编码,
+和空格被服务端解释成同一个东西
验签名之前,先把待签名的原始字符串 xxd 出来看一眼,
比对着文档逐字比对快得多。
五、保留一次完整的成功样本
接口调通之后,把「请求头 + 请求体 + 响应头 + 响应体」完整存一份到本地, 并记下当时的参数。以后接口改版、字段变化,有这份基线就能快速判断是哪里变了, 不用从头再试一遍。
存样本的时候记得把 token、密钥这类东西替换掉,不要原样留在文件里。 这一点比省下的时间重要。← 返回笔记列表