[Eval][v3][zh] Order service OOM crashloop following v3.7 deploy
service: order-svccreated: 6/2/2026, 11:55:04 PM
Raw incident context
Time: 09:15 UTC. order-svc pods entering CrashLoopBackOff with OOMKilled exit reason. Kubernetes: - Pods: 12 total, 3 currently OOMKilled, 9 running - Memory limit: 512Mi, requests: 256Mi - Recent restarts/hour: 18 (up from baseline of 0–1) - HPA scaling has hit max replicas (12) Memory trend (last 24h): - Steady linear growth from 180Mi at 04:00 UTC to 500Mi at 09:00 UTC, then crash - Pre-deploy baseline: stable at 200Mi indefinitely Deploy history: - 04:00 UTC — order-svc v3.7 deployed (rolling, 100% complete by 04:08) - Changelog: "switched JSON parser to fast-json-stringify; added in-process request cache (Map-based, no eviction)" Logs: - No FATAL/ERROR pattern; pods exit silently - Heap profile from one captured pod shows: ~340Mi held by Map keyed on request ID, never cleared On-call: - 09:12 — first OOMKilled pod - 09:14 — pager - 09:16 — service still serving most traffic via remaining pods; checkout success rate dipped from 99.7% → 96.8%
Summary
order-svc 自 09:12 UTC 起出现 Pod OOMKilled 重启循环,p99 延迟升高,约 3% 请求超时。根因是 v3.7 部署引入的内存泄漏:一个基于 Map 的请求缓存未设置淘汰策略,导致内存线性增长直至 OOM。当前 12 个 Pod 中 3 个已 OOMKilled,HPA 已达最大副本数。
Severity reasoning: 用户可见的故障:结账成功率从 99.7% 降至 96.8%(>1% 错误率超过 5 分钟),且影响收入路径。符合 SEV1 定义。
deepseek-chat·prompt v3·output: zh·10458ms·2418↑ / 1564↓ tok·$0.00237
Root cause hypotheses
- highv3.7 部署引入的请求缓存 Map 未设置淘汰策略,导致内存泄漏
Evidence: 堆分析显示约 340Mi 内存被以请求 ID 为键的 Map 持有,且从未清理。部署后内存从 180Mi 线性增长至 500Mi 后 OOM。
- lowfast-json-stringify 库存在内存泄漏
Evidence: 无直接证据;堆分析未显示序列化相关对象异常增长。
- low外部依赖(如数据库连接池)未正确释放资源
Evidence: 日志无数据库相关错误,且内存增长模式与请求缓存一致。
Investigation checklist
- 确认内存泄漏源:检查堆中 Map 对象大小
kubectl exec -n prod $(kubectl get pod -n prod -l app=order-svc -o jsonpath='{.items[0].metadata.name}') -- jcmd 1 GC.heap_dump /tmp/heap.hprof && kubectl cp -n prod $(kubectl get pod -n prod -l app=order-svc -o jsonpath='{.items[0].metadata.name}'):/tmp/heap.hprof ./heap.hprofExpected: heap.hprof 中显示大量 com.example.OrderCache 实例,每个持有请求 ID 字符串
- 验证缓存未设置淘汰策略:检查代码中 Map 声明
kubectl exec -n prod $(kubectl get pod -n prod -l app=order-svc -o jsonpath='{.items[0].metadata.name}') -- cat /app/app.jar | strings | grep -i 'new HashMap'Expected: 输出显示无大小限制或淘汰策略的 HashMap 实例化
- 确认内存增长趋势与请求速率相关
kubectl exec -n prod $(kubectl get pod -n prod -l app=order-svc -o jsonpath='{.items[0].metadata.name}') -- curl -s localhost:8080/metrics | grep -E 'http_requests_total|process_resident_memory_bytes'Expected: 内存使用量随请求总数线性增长
- 检查 HPA 是否已到上限
kubectl get hpa -n prod order-svc-hpaExpected: 当前副本数 12/12,已达最大
Mitigation plan
回滚 order-svc 至 v3.6(上一个稳定版本)
Risk: 回滚期间服务短暂不可用(约 30 秒),但可恢复。
Rollback: 再次执行 kubectl rollout undo deployment/order-svc -n prod 可回到 v3.7
若回滚不可行,临时增加 Pod 内存限制至 1Gi 并重启所有 Pod
Risk: 仅缓解症状,不解决泄漏;可能耗尽节点资源。
Rollback: 将内存限制改回 512Mi 并重启 Pod
在 v3.7 中为缓存添加 TTL 淘汰策略(如 5 分钟)并重新部署
Risk: 代码修改需时间,且可能引入新 bug。
Rollback: 回滚至 v3.6
Customer impact
部分用户在下单时遇到超时或错误,结账成功率从 99.7% 下降至 96.8%。影响持续约 15 分钟,预计回滚后恢复。
Postmortem draft
摘要
order-svc 因 v3.7 部署引入的内存泄漏导致 Pod OOM 重启,影响结账成功率。
时间线 (UTC)
- 04:00 - v3.7 部署完成
- 09:12 - 首个 Pod OOMKilled
- 09:14 - 分页告警
- 09:16 - 确认影响,开始调查
- [FILL IN] - 回滚完成
影响
- 结账成功率 99.7% → 96.8%
- p99 延迟升高
- 3 个 Pod OOMKilled
根因
v3.7 新增的请求缓存 Map 未设置淘汰策略,导致内存线性增长直至 OOM。
检测
告警延迟约 12 分钟(从部署到首次 OOM)。
响应
回滚至 v3.6 恢复。
做得好的
- 快速定位到内存泄漏
- 回滚流程顺利
做得不好的
- 代码审查未发现缓存无淘汰策略
- 无内存使用告警
行动项
- [ ] 为缓存添加 TTL 淘汰
- [ ] 设置内存使用率告警
- [ ] 增加预发布环境内存压力测试
Follow-ups
- P0为 order-svc 的请求缓存添加 TTL 淘汰策略,并设置最大条目数— service owner
- P1配置 Pod 内存使用率告警(>80% limit 持续 5 分钟)— platform team
- P1在预发布环境中增加内存泄漏检测(如 heap dump 对比)— QA team
- P2审查 v3.7 代码变更,确保无其他类似问题— service owner
Similar past incidents
lexical match (pg_trgm)
- 36%
[Eval][v1][en] Order service OOM crashloop following v3.7 deploy
Pods OOM-killed every ~20min, restart loop, p99 latency degraded, ~3% requests timing out
- 34%
[Eval][v2][en] Order service OOM crashloop following v3.7 deploy
Pods OOM-killed every ~20min, restart loop, p99 latency degraded, ~3% requests timing out
- 19%
[Eval][v1][zh] Payment service connection pool exhaustion after batch job deploy
p99 latency 4.8s (up from 120ms), 12% 500 error rate, customers report failed checkouts
- 19%
[Eval][v2][zh] Payment service connection pool exhaustion after batch job deploy
p99 latency 4.8s (up from 120ms), 12% 500 error rate, customers report failed checkouts
- 17%
[Eval][v1][en] Payment service connection pool exhaustion after batch job deploy
p99 latency 4.8s (up from 120ms), 12% 500 error rate, customers report failed checkouts