← All incidents

[Eval][v1][zh] Order service OOM crashloop following v3.7 deploy

service: order-svccreated: 6/2/2026, 11:51:44 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

SEV2

order-svc 自 04:00 UTC 部署 v3.7 后,内存持续线性增长,约每 20 分钟触发 OOMKilled,导致 Pod 重启循环。当前 3 个 Pod 已 OOM,9 个运行中,p99 延迟升高,3% 请求超时,结账成功率从 99.7% 降至 96.8%。根因是新增的进程内请求缓存(Map)未设置淘汰策略,导致内存泄漏。

Severity reasoning: 影响用户结账流程(成功率下降 2.9%),但服务仍部分可用,未完全中断,且无数据丢失或损坏。属于 SEV2:部分用户显著降级。

deepseek-chat·prompt v1·output: zh·9323ms·1786↑ / 1408↓ tok·$0.00203

Root cause hypotheses

  • highv3.7 新增的进程内请求缓存(Map-based, no eviction)未设置淘汰策略,导致内存持续增长直至 OOM。

    Evidence: 堆分析显示约 340Mi 被以请求 ID 为键的 Map 持有,且从未清理;内存趋势从部署后线性增长。

  • lowfast-json-stringify 库存在内存泄漏,序列化过程中分配的对象未释放。

    Evidence: 切换 JSON 解析器是 v3.7 的唯一其他变更,但堆分析未显示序列化相关对象异常增长。

  • medium外部依赖(如数据库连接池)未正确关闭,导致连接泄漏。

    Evidence: 内存增长模式与请求量相关,但堆分析未显示连接对象异常;且连接泄漏通常不会导致如此线性的增长。

Investigation checklist

  1. 确认当前内存使用趋势
    kubectl top pod -l app=order-svc --sort-by=memory

    Expected: 显示内存使用从 180Mi 到接近 limit 的线性增长

  2. 检查 v3.7 变更内容
    kubectl rollout history deployment/order-svc --revision=latest

    Expected: 确认镜像标签为 v3.7,变更日志包含缓存添加

  3. 获取一个正在运行的 Pod 的堆转储
    kubectl exec -it <pod-name> -- jcmd 1 GC.heap_dump /tmp/heap.hprof

    Expected: 生成堆转储文件,后续分析可确认 Map 对象大小

  4. 检查缓存相关代码(如果可访问)
    grep -r 'Map' /path/to/order-svc/src --include='*.js' | grep -i 'cache'

    Expected: 找到无淘汰策略的 Map 缓存实现

Mitigation plan

  • 立即回滚 order-svc 至 v3.6(上一个稳定版本)

    Risk: 回滚期间可能有短暂连接中断(约 30 秒),但服务应快速恢复。

    Rollback: 如果回滚后问题未解决,重新部署 v3.7 并启用更激进的内存限制

  • 临时增加 Pod 内存限制至 1Gi,以争取时间分析根因

    Risk: 可能掩盖问题,且集群资源可能不足。

    Rollback: 恢复内存限制至 512Mi

  • 在 v3.7 中通过环境变量禁用缓存功能(如果支持)

    Risk: 可能影响性能,但不会导致 OOM。

    Rollback: 重新启用缓存

Customer impact

约 3% 的结账请求超时或失败,p99 延迟升高,但大部分用户仍可正常下单。影响从 09:12 开始,预计回滚后 10 分钟内恢复。

Postmortem draft

Postmortem: order-svc OOMKilled 循环

摘要

[简要描述事件]

时间线

  • 04:00 UTC: 部署 v3.7
  • 09:12 UTC: 首次 OOMKilled
  • 09:14 UTC: 触发告警
  • 09:16 UTC: 开始调查
  • [回滚时间]: 回滚至 v3.6

影响

  • 结账成功率从 99.7% 降至 96.8%
  • 3% 请求超时
  • 3 个 Pod 持续 OOM

根因

v3.7 新增的进程内请求缓存(Map)未设置淘汰策略,导致内存泄漏。

做得好的

  • 快速检测到 OOM 并触发告警
  • 堆分析快速定位到缓存问题

做得不好的

  • 代码审查未发现缓存无淘汰策略
  • 未在预发布环境进行长时间内存压力测试

行动项

  • [ ] 为缓存添加 TTL 和最大条目限制
  • [ ] 添加内存使用监控告警
  • [ ] 在 CI 中集成内存泄漏检测

Follow-ups

  • P0为进程内缓存添加 TTL 和最大条目限制,并代码审查service owner
  • P1添加 Pod 内存使用率告警(>80% limit)on-call SRE
  • P1在预发布环境执行 24 小时内存压力测试platform team
  • P2审查 fast-json-stringify 是否存在已知内存问题service owner