← All incidents

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

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

SEV1

order-svc 自 09:12 UTC 起出现 Pod OOMKilled 重启循环,p99 延迟升高,约 3% 请求超时。根本原因是 v3.7 部署引入的内存泄漏:基于 Map 的请求缓存未设置淘汰策略,导致内存线性增长直至触发 512Mi 限制。当前 3 个 Pod 已崩溃,剩余 9 个 Pod 内存使用接近上限,存在级联故障风险。

Severity reasoning: 用户可见故障:结账成功率从 99.7% 降至 96.8%,超过 1% 阈值;错误率约 3% 持续超过 5 分钟;收入路径(结账流程)受损。符合 SEV1 定义。

deepseek-chat·prompt v3·output: zh·10558ms·2418↑ / 1648↓ tok·$0.00247

Root cause hypotheses

  • highv3.7 部署中新增的基于 Map 的请求缓存未设置淘汰策略,导致内存泄漏。

    Evidence: 堆分析显示约 340Mi 被以请求 ID 为键的 Map 持有,且从未释放;内存从 04:00 部署后从 180Mi 线性增长至 500Mi。

  • lowfast-json-stringify 库存在内存泄漏或过度分配。

    Evidence: 无直接证据;堆分析未显示序列化相关对象异常。

  • lowKubernetes 内存限制设置过低,无法应对正常流量峰值。

    Evidence: 基线内存 200Mi 稳定运行,v3.7 后增长模式异常,非正常波动。

Investigation checklist

  1. 确认内存泄漏源:检查堆中 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.hprof

    Expected: heap.hprof 中 Map 对象持有大量请求 ID 字符串,无清除逻辑

  2. 验证缓存未设置淘汰策略:检查代码中 Map 使用
    kubectl exec -n prod $(kubectl get pod -n prod -l app=order-svc -o jsonpath='{.items[0].metadata.name}') -- cat /app/app.js | grep -A 20 'new Map'

    Expected: 显示 Map 初始化,无 eviction 或 size limit 相关代码

  3. 检查内存增长趋势是否与请求量相关
    kubectl top pod -n prod -l app=order-svc --sort-by=memory | head -10

    Expected: 内存使用最高的 Pod 对应最近处理请求数最多的 Pod

  4. 确认 fast-json-stringify 无异常分配
    kubectl exec -n prod $(kubectl get pod -n prod -l app=order-svc -o jsonpath='{.items[0].metadata.name}') -- jcmd 1 GC.class_histogram | grep -i 'fastjson\|stringify'

    Expected: 无异常大对象或持续增长

Mitigation plan

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

    Risk: 回滚期间可能短暂中断,但可快速恢复稳定状态

    Rollback: 重新部署 v3.7(但需先修复内存泄漏)

  • 如果回滚不可行,临时增加内存限制至 1Gi 并重启所有 Pod

    Risk: 仅缓解症状,不解决根本问题;可能掩盖其他问题

    Rollback: 恢复原限制 512Mi

  • 在回滚后,手动删除残留的缓存 Map 相关 Pod 确保干净状态

    Risk: 删除 Pod 会导致短暂流量损失,但由其他副本接管

    Rollback: 无,删除操作不可逆,但可通过重新部署恢复

Customer impact

部分用户在下单结账时遇到超时或失败,结账成功率从 99.7% 下降至 96.8%。预计影响约 3% 的结账请求。团队正在回滚至稳定版本,预计 15 分钟内恢复。

Postmortem draft

摘要

order-svc 在 v3.7 部署后因内存泄漏导致 Pod OOMKilled,影响结账成功率。

时间线 (UTC)

  • 04:00 - v3.7 部署完成
  • 09:12 - 首个 OOMKilled Pod
  • 09:14 - 分页告警
  • 09:16 - 确认影响,开始调查
  • [FILL IN] - 回滚完成

影响

  • 结账成功率从 99.7% 降至 96.8%
  • 3 个 Pod 崩溃,9 个 Pod 内存使用接近上限
  • p99 延迟升高

根因

v3.7 引入的基于 Map 的请求缓存未设置淘汰策略,导致内存线性增长直至 OOM。

检测

告警由 OOMKilled 事件触发,但内存增长趋势在 04:00 后即可发现。

响应

  • 09:14 分页响应
  • 09:16 开始调查
  • 回滚决策和执行

做得好

  • 快速识别内存泄漏
  • 及时回滚

做得不好

  • 未在预发布环境发现内存泄漏
  • 缺乏内存增长告警

行动项

  • [FILL IN] 修复缓存淘汰策略
  • [FILL IN] 添加内存增长告警
  • [FILL IN] 增加预发布内存测试

Follow-ups

  • P0修复 order-svc 中 Map 缓存,添加 LRU 淘汰或大小限制order-svc 服务负责人
  • P1添加内存使用率增长告警,当内存使用超过限制 80% 且持续增长时触发on-call SRE
  • P1在预发布环境增加内存泄漏检测测试(如 heap dump 对比)平台团队
  • P2审查 fast-json-stringify 库的内存安全性order-svc 服务负责人