自建探针:二十行脚本监控你的 API 供应商
目标:先要知道「什么时候坏了」
监控的第一目标不是「优化」,是发现故障。而发现故障的最低要求是:
- 定期探测;
- 有基线;
- 异常时通知你。
这三件事不需要监控系统,二十行脚本就够。
探针的两个层级
层级一:可达性与延迟
最简单的探测 —— 发一个最小请求,记录成功/失败与耗时。
#!/usr/bin/env bash
# probe.sh —— 用最小请求探测一家站
BASE="https://<域名>/v1"
KEY="<KEY>"
MODEL="<模型名>"
START=$(date +%s%N)
HTTP=$(curl -s -o /tmp/probe_body -w '%{http_code}' \
--max-time 20 \
"$BASE/chat/completions" \
-H "Authorization: Bearer $KEY" \
-H 'Content-Type: application/json' \
-d "{\"model\":\"$MODEL\",\"max_tokens\":1,
\"messages\":[{\"role\":\"user\",\"content\":\"1\"}]}")
END=$(date +%s%N)
MS=$(( (END - START) / 1000000 ))
echo "$(date -Is)\t$HTTP\t${MS}ms"
要点:
max_tokens: 1—— 让探测请求尽可能便宜。探测成本必须接近零,否则你不会愿意高频探测;--max-time 20—— 必须有超时,否则脚本会挂住;- 记录 HTTP 状态码和耗时两个字段,缺一不可。
层级二:真实性
可达性只能告诉你「它在不在」。要发现「它在降智 / 换后端」,需要带判据的探测。
一个低成本的做法:用一个答案确定的问题,检查返回内容。
例如:「1+1 等于几?只回答数字。」
- 正常:返回
2; - 被替换成弱模型:可能返回「2」以外的内容,或答非所问;
- 被静默降级:返回长段解释(说明它没有遵守「只回答数字」)。
注意:单次不通过不能下结论(模型有随机性)。连续 N 次不通过才有意义 —— 建议 N = 3。
这一层不要做得太重:它的价值在于发现「行为变化」,不在于精确评估质量。用最简单、答案最确定的题目即可。
探测间隔与超时的取值
| 参数 | 建议值 | 理由 |
|---|---|---|
| 探测间隔 | 5–15 分钟 | 更密会被限流;更疏会滞后太多 |
| 单次超时 | 15–20 秒 | 低于 10 秒会误报;高于 30 秒会拖慢整轮 |
| 连续失败阈值 | 3 次 | 单次失败大概率是抖动 |
| 判为恢复 | 连续 2 次成功 | 避免「恢复-失败-恢复」的消息轰炸 |
为什么「连续 3 次失败才告警」:单次失败太常见(网络抖动、上游瞬时 5xx)。每次都告警的结果是你开始忽略告警 —— 那监控就失效了。
为什么「恢复也需要连续 2 次」:否则一次侥幸成功就会发出恢复通知,而实际还在故障中。
三个必须避开的坑
坑一:探测频率过高被限流
后果:你的探测请求本身触发了限流,导致「探测显示不可用,实际业务正常」的假故障。
这一条尤其容易发生:如果你监控 10 家站、每 1 分钟探一次,就是每分钟 10 个请求,看起来不多;但如果多家站共享同一个上游账号池,或者你同时还在跑业务,累积起来就可能触发阈值。
做法:
- 探测间隔 ≥ 5 分钟;
- 探测用的 Key 与业务 Key 分开(站方支持多 Key 的话);
- 探测请求用最小
max_tokens。
坑二:把业务错误算成可用性故障
问题:有些失败不是供应商的问题,而是你请求本身的问题。
区分:
| 状态码 | 含义 | 算不算故障 |
|---|---|---|
| 200 | 正常 | 否 |
| 401 / 403 | Key 或权限问题 | 不算(是你的配置问题) |
| 429 | 限流 | 部分算(可能是你超速,也可能是它限制过严) |
| 400 | 请求格式问题 | 不算 |
| 5xx | 服务端错误 | 算 |
| 超时 / 连接失败 | 网络或服务不可达 | 算 |
关键:401 和 400 必须排除在可用性统计之外,否则你换一次 Key 就会看到一堆「故障」。
同理,429 要单独统计 —— 它反映的是「容量受限」,与「服务挂了」是两件事。
坑三:用单次测量做结论
问题:单次探测得到 3000ms,不能说明它慢。网络抖动、第一次 TLS 握手、DNS 缓存都可能造成偏差。
做法:
- 记录分位数而不是平均值。至少要 p50 和 p95。平均 500ms 但有 5% 的请求卡到 10 秒,用户体验是「偶尔卡死」;
- 单次异常值不触发告警,看连续趋势;
- 如果条件允许,从两个不同网络位置探(比如你的服务器 + 一台云主机),可以区分「站点问题」和「你的网络问题」。
存储与告警
存储:一行一条记录就够,字段:时间 / 站点 / 状态码 / 耗时ms / 是否成功。SQLite 或纯文本都行。
告警:最简单的可靠方式是 Webhook(发到企业微信/钉钉/飞书机器人)。内容包含:
[API 监控] <站点名> 连续 3 次失败
最近状态:500 / 超时 / 超时
最后成功时间:2026-10-06 14:20
注意告警内容要给「最后成功时间」 —— 它让你一眼判断是刚坏还是坏了很久。
一个不要自己做的事
不要自己实现复杂的监控系统。 探针的目标是「知道坏了」,这二十行就能做到。指标聚合、可视化、趋势分析这些如果自己写,会消耗大量时间而收益有限。
如果你的团队已有监控体系(Prometheus 等),把探针结果推到那里,用现成的告警与看板。这是最省事的路径。
顺带一提
本站「可用率监测」页的数据,也是用同类方法(定时探测 + 分档统计)得到的,口径写在《可用率是怎么测出来的》那篇里。
但请注意:本站的探测是从我们这一台服务器的视角做的。你自己的网络环境、你实际调用的模型、你的并发模式都与我们不同。
所以:本站的数据适合用来做「横向比较」和「筛选」,不适合替代你自己的探针。 两者是互补关系 —— 我们给你一个广度的视角,你的探针给你一个贴合自身场景的深度视角。
这篇文章对你有帮助吗?如果你在实际使用中发现了文中没提到的情况,欢迎 提交纠错或补充,我们会核验后更新到正文里。
相关文章
顺着看下去:本站收录的部分中转站
本文没有指向特定模型系列,下面是本站收录站点中综合评分靠前的几家,供你顺着看下去。排序依据是评分与可用率,不构成推荐。