记一次诡异的"偶发 404"排查:CDN 回源到 OSS 导致 REST API 失败
现象:接口"有时成功,有时失败"
某天,我们团队突然收到告警:生产环境的一个关键接口:
https://ewc-dev.kone.cn/contract/ser/getSerLisContractReviewDOA
出现了 偶发性 404 错误。更诡异的是:
-
用
curl调用,第一次成功,第二次失败,第三次又成功...... -
响应内容时而是 JSON 数据,时而返回一段 XML 错误:
<Error>NoSuchKey<Message>The specified key does not exist.</Message> <HostId>xxaixqy.xu.cn</HostId> <Key>contract/ser/getSerLisContractReviewDOA</Key> </Error>
这看起来像是 OSS(对象存储)的错误响应 ,但我们明明是在调用一个 REST API,怎么会打到 OSS 上?
初步排查:DNS 和证书正常
我们先检查了基础配置:
nslookup ewc-dev.kone.cn
# 返回 IP 正常,无异常 CNAME
HTTPS 证书也有效,域名匹配。网络层和 TLS 层都正常。
但问题依旧:请求随机失败。
深入分析:从响应头发现线索
使用 curl -I 查看响应头:
curl -I https://ewc-dev.kone.cn/contract/ser/getSerLisContractReviewDOA
多次请求后,发现了规律:
成功时的响应头:
HTTP/2 200
Content-Type: application/json
X-Cache: HIT FROM CDN
Age: 120
Server: Tengine
失败时的响应头:
HTTP/2 404
Content-Type: application/xml
Server: AliyunOSS
X-Oss-Request-Id: 6900938624FA4D30333F2DBE
X-Cache: MISS
关键线索出现了:
Server: AliyunOSS→ 明确表示这是 OSS 返回的响应X-Cache: MISS→ 表示 CDN 缓存未命中,触发了回源Age: 120→ 缓存已存在 120 秒
结论:这个请求本应由后端服务处理,但却被 CDN 回源到了 OSS!
根本原因:CDN 源站配置错误
我们登录阿里云控制台,查看 xxaixqy.xu.cn 的 CDN 配置:
| 配置项 | 当前值 |
|---|---|
| 源站类型 | OSS |
| 源站地址 | ewc-dev.oss-cn-shanghai.aliyuncs.com |
问题找到了!
CDN 的源站被错误地配置为了 OSS Bucket,而不是后端应用服务器。
这意味着:
- 当 CDN 缓存命中时 → 返回之前缓存的 JSON 响应 → ✅ 成功
- 当 CDN 缓存未命中时 → 回源到 OSS → OSS 把
/contract/ser/...当作文件路径查找 → 找不到 → 返回NoSuchKey→ ❌ 失败
这就是"偶发性成功"的根源。
为什么会出现这种错误配置?
进一步调查发现:
xxaixqy.xu.cn最初是用于部署前端静态资源的,因此 CDN 源站指向了 OSS。- 后来,开发团队为了方便,直接复用了这个域名作为后端 API 的入口。
- 但没有修改 CDN 源站,导致所有 API 请求都被当作静态资源处理。
解决方案
- 修改 CDN 源站:将源站从 OSS 改为后端服务地址(SLB 或网关)
- 拆分域名 (推荐):
- 静态资源:
static-dev.kone.cn→ 指向 OSS - REST API:
api-dev.kone.cn→ 指向 SLB
- 静态资源:
- 设置合理的缓存策略:对只读接口可缓存,写操作不缓存
它提醒我们:
在微服务和 CDN 普及的今天,我们不仅要关注代码逻辑,更要理解流量背后的每一跳。
一个小小的配置错误,就可能导致"玄学故障"。只有深入底层,才能真正解决问题。
如果你也遇到过类似的"偶发故障",欢迎在评论区分享你的排查经历!