← All incidents

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

service: order-svccreated: 6/2/2026, 11:52:12 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: 用户可见的结账成功率下降(96.8%),但服务仍部分可用,未完全中断,且无数据丢失。影响范围约 3% 的请求超时,属于显著降级,符合 SEV2 定义。

deepseek-chat·prompt v1·output: zh·8605ms·1786↑ / 1311↓ tok·$0.00192

Root cause hypotheses

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

    Evidence: Heap profile 显示 ~340Mi 被 Map 持有,key 为 request ID,且从未清理。

  • lowJSON 解析器切换(fast-json-stringify)存在内存分配异常,导致对象无法回收。

    Evidence: 无直接证据,但切换解析器可能引入内存碎片或泄漏。

  • medium上游服务请求量突增导致缓存膨胀,但 HPA 已达上限。

    Evidence: 内存增长趋势线性而非突发,且无请求量突增告警。

Investigation checklist

  1. 确认缓存 Map 大小和增长速率
    kubectl exec <pod-name> -- node -e "console.log(global.cache?.size)"

    Expected: 输出应显示 Map 大小持续增长,且无减少

  2. 检查 v3.7 部署的变更详情
    kubectl rollout history deployment/order-svc --revision=latest

    Expected: 确认变更包含 'added in-process request cache'

  3. 查看当前运行 Pod 的内存使用趋势
    kubectl top pod -l app=order-svc --sort-by=memory

    Expected: 内存使用接近 500Mi,且持续上升

  4. 检查是否有内存泄漏的 heap dump 证据
    kubectl exec <pod-name> -- node --inspect -e "global.gc(); console.log(process.memoryUsage().heapUsed)"

    Expected: heapUsed 应远低于 limit,但实际可能接近 500Mi

Mitigation plan

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

    Risk: 回滚期间可能有短暂连接中断,但风险低

    Rollback: 重新部署 v3.7(若回滚后问题解决,则无需 rollback)

  • 若无法回滚,则临时增加 Pod 内存 limit 至 1Gi,并重启所有 Pod

    Risk: 可能掩盖根本问题,且资源消耗增加

    Rollback: 恢复内存 limit 至 512Mi,并重新部署 v3.7

Customer impact

约 3% 的结账请求超时,p99 延迟升高,但服务整体可用。受影响用户会看到结账失败或超时错误。预计在回滚后 10 分钟内恢复。

Postmortem draft

Postmortem: order-svc OOMKilled 循环

摘要

[2-3 句概述]

时间线

  • 04:00 UTC: 部署 v3.7
  • 09:12 UTC: 首次 OOMKilled
  • 09:14 UTC: 分页告警
  • 09:16 UTC: 确认影响
  • [回滚时间]

影响

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

根因

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

做得好的

  • 快速识别内存增长模式
  • 及时回滚

做得不好的

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

行动项

  • [ ] 为缓存添加 TTL 和最大条目限制
  • [ ] 添加内存使用告警
  • [ ] 更新部署流程,要求性能测试

Follow-ups

  • P0为进程内缓存添加 TTL 和最大条目限制service owner
  • P1添加内存使用率告警(>80% limit)on-call SRE
  • P1审查 v3.7 代码变更,确保无其他泄漏service owner
  • P2更新部署流程,要求 staging 环境运行 1 小时压力测试platform team