华为云ECS上排查进程被OOM终止:从内核日志到内存限制
先分清宿主机与服务限制
进程突然消失不一定表示整台 ECS 的物理内存耗尽。Linux 会回收可回收缓存;系统级 OOM、systemd 服务或容器的 cgroup 限额、应用自身退出及人工结束,都可能表现为进程不在了。先记录故障时间、服务名和重启情况,再找证据。单凭 exit 137 不能证明 OOM:它通常表示进程收到 SIGKILL,也可能来自人工操作或外部守护程序。
一、先查内核事件
在有权限的主机上查看内核日志:
sudo journalctl -k --since today
把时间范围收窄到故障前后,寻找 OOM、被选中终止的进程名、PID、内存使用及 cgroup 相关提示。不同内核版本的日志措辞不同;日志也可能因轮转或重启而不完整。没有找到记录不等于从未发生 OOM,应结合监控、服务日志和容器运行时记录核对。
二、看整体内存与当前进程
free -h
ps -eo pid,comm,rss --sort=-rss | head -n 15
free -h 的 available 更适合估算无需交换即可供新任务使用的内存;free 较小并不单独代表故障,buff/cache 中有不少可回收缓存。ps 的 RSS 是进程当前驻留内存,单位为 KiB;共享页可能在多个进程的 RSS 中重复计数。被 OOM 杀掉的进程已经退出,当前列表只是一张事后快照,不能代替故障时的历史数据。
三、检查 systemd 服务限制
将 SERVICE_NAME 换成实际服务单元,读取 systemd 记录的限制、用量和 cgroup 路径:
systemctl show SERVICE_NAME -p MemoryMax -p MemoryCurrent -p ControlGroup
MemoryMax 是该单元的内存上限,MemoryCurrent 是当前用量;具体属性和值随 systemd 版本而异。若显示无限制,也只能说明该层没有设置此项上限,不能排除容器、父级 cgroup 或宿主机整体限制。检查服务是否频繁重启,并将限制值和故障时段的内存曲线对照。
四、按 cgroup v2 证据判断
cgroup v2 常见控制文件包括 memory.max 和 memory.events。先依据 ControlGroup 找到服务实际所在的 cgroup 子目录,再读取该目录中的文件;不要把顶层目录的值误当成某个服务的值。示例查看顶层控制组:
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.events
memory.max 中的 max 表示该组未设置此项上限,数字以字节计。memory.events 常见计数包括 high、max、oom 和 oom_kill;内核版本、发行版及容器命名空间会影响可见文件和计数范围。故障前后 oom 或 oom_kill 计数增加,且内核日志指向同一服务 cgroup,才是服务限额触发的重要证据。容器内部看到的路径可能被命名空间隔离;必要时请有权限的宿主机管理员核验。
五、交叉验证并安全处置
若内核记录显示全局内存不足,关注整机 available、同时运行的服务和故障时监控;若 cgroup 计数增长且服务达到 MemoryMax,更像是该服务或容器限额触发。工具版本不支持 cgroup v2 时,相关文件可能不存在,应先确认实际控制器和发行版配置,不能把缺失文件当作没有限制。
确认原因后再评估降低并发、优化内存峰值、调整合理限额或扩容;任何限制变更都应按维护流程审批并监控回退。不要为掩盖问题而盲目重启、关闭 OOM 机制或清空缓存。本文是通用排查方法,不代表已在任何实际 ECS 上执行或验证。
- 点赞
- 收藏
- 关注作者
评论(0)