退出码 137 是什么
137 是 128 加 9 的结果,表示进程被 SIGKILL 信号杀死。SIGKILL 无法被捕获与忽略,因此进程没有机会做清理工作。容器场景下它主要有三个来源:内存超限被内核终止、docker stop 宽限期结束后被强杀、以及有人显式执行了 kill。定位的关键不是看到数字就下结论,而是区分这三种来源。
基本信息
| 含义 | 128+9,进程收到 SIGKILL 终止 |
|---|---|
| 查看命令 | docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' 容器 |
| 三个来源 | 内存超限、停止超时强杀、显式 kill |
| 辅助命令 | docker events --filter event=oom,宿主 dmesg 中的 OOM 记录 |
| 相关字段 | .HostConfig.Memory 内存上限、.State.FinishedAt 结束时间 |
| 同类码 | 143 是 128+15(SIGTERM),属正常停止流程 |
典型使用场景
- 服务突然重启且日志末尾无报错:先确认是否 137
- 大内存任务跑一半被杀:核查内存上限与峰值
- 停止操作耗时很长后容器消失:确认是否宽限期超时被强杀
- 编排平台滚动更新后实例异常:区分正常终止与强制终止
- 监控告警配置:把 137 单独分类,避免与业务错误混在一起
三种来源的区分
三种来源的区分
# 一、拿到退出码与 OOM 标记
docker inspect -f 'exit={{.State.ExitCode}} oom={{.State.OOMKilled}} mem={{.HostConfig.Memory}}' web
# 二、查看是否发生过 OOM 事件
docker events --filter container=web --filter event=oom --since 24h
# 三、宿主侧记录:区分是容器超限还是宿主整体内存紧张
dmesg | grep -i -E 'oom|killed process' | tail -20
# 四、确认是否有人停止了容器:events 里会有 stop/kill 记录
docker events --filter container=web --since 2h | tail -20来源判读
| 线索组合 | 判读结论 | 处理方向 |
|---|---|---|
| OOMKilled=true | 容器内存超限被内核终止 | 调大限额或排查内存增长 |
| OOMKilled=false 且宿主有 OOM 记录 | 宿主整体内存紧张波及容器 | 优化宿主容量与共居服务 |
| events 中有 stop/kill 且时间点吻合 | 人为或平台操作导致 | 核对发布流程与告警来源 |
| 日志在末尾突然截断 | 没来得及写退出日志,符合强杀特征 | 调整停止宽限期或优化优雅退出 |
| 伴随内存曲线持续爬升 | 疑似内存泄漏 | 抓取样本做长期观察 |
确认是内存问题后有三条路:合理调大限额、修复内存泄漏、调整运行时堆参数。单纯加交换空间只会把强杀推迟并让整体性能变差,不解决根因。
docker stop 会先发 TERM 并等待宽限期(默认十秒),超时才发 KILL。如果应用优雅退出耗时较长,应调大停止超时,否则每次重启都等价于一次强杀。