systemd 的 MemoryLimit 参数已在较新版本中被废弃,现代系统应使用 MemoryMax 参数限制服务内存。当服务内存超过设定值时,systemd 会触发 OOM Killer 终止该服务进程,防止占用过多系统资源。
先说结论:MemoryLimit 已废弃,新系统请使用 MemoryMax 设置硬限制,超过限制服务会被强制杀死。
- 适用场景:需要防止单个服务内存无限增长导致系统宕机的生产环境。
- 先准备:确认 systemd 版本,v231 之后建议使用 MemoryMax 替代 MemoryLimit。
- 再验证:修改配置后重启服务,观察 systemctl status 中的 Memory 字段和系统日志。
命令速用版
直接通过 systemctl edit 创建覆盖配置,设置内存上限为 500MB(根据实际需求调整数值):
systemctl edit <服务名>
[Service]
MemoryMax=500M
保存退出后重载配置并重启服务:
systemctl daemon-reload
systemctl restart <服务名>
为什么会这样
systemd 通过 cgroups 机制管理资源,内存限制触发后会由内核 OOM Killer 介入。
早期 systemd 版本使用 MemoryLimit 参数,但在 systemd v231 版本后该参数被标记为废弃,后续版本中移除,统一由 MemoryMax 接管。设置该限制的本质是利用 Linux cgroups 的 memory.limit_in_bytes 或 memory.max 接口,当进程组内存使用量超过阈值,内核会发送 SIGKILL 信号终止进程,从而保护系统其他部分不被拖垮。
分步处理
第一步:确认 systemd 版本
执行命令 systemctl `--version` 查看版本。如果版本较老(v231 之前),可以使用 MemoryLimit;新版本必须使用 MemoryMax。
第二步:编辑服务配置
使用 systemctl edit <服务名> 命令,这会创建一个覆盖配置文件。在编辑器中输入:
[Service]
MemoryMax=500M
如果是旧版本 systemd,则使用 MemoryLimit=500M。
第三步:重载并重启
执行 systemctl daemon-reload 使配置生效,然后执行 systemctl restart <服务名> 重启服务。
第四步:设置重启策略(可选但建议)
防止内存泄漏导致服务频繁崩溃后无法恢复,建议同时配置 Restart=on-failure 和 RestartSec=10。
怎么验证是否生效
检查状态显示
运行 systemctl status <服务名>,输出信息中会显示当前内存使用量,例如 Memory: 120.0M。
查看日志记录
如果服务因超限被杀,日志中会出现 OOM 相关记录。使用 journalctl -u <服务名> -f 查看实时日志,或检查 dmesg | grep -i "out of memory"。
压力测试验证
在测试环境人为制造内存负载,观察服务是否在达到设定值后被 systemd 终止并记录退出码。
常见坑
版本兼容性错误
在新版 systemd 上继续使用 MemoryLimit 会导致配置被忽略且无报错,服务实际上无内存限制。务必确认使用 MemoryMax。
限制过窄导致循环重启
如果设置的内存上限低于服务正常启动所需内存,服务会启动即被杀,触发 Restart 策略进入无限重启循环。建议先观察服务正常峰值再设定阈值。
忽略 Swap 影响
MemoryMax 通常限制的是 RSS 内存,部分配置下可能包含或不包含 Swap,需结合 MemorySwapMax 一起管理,否则服务可能通过占用 Swap 绕过限制。
常见问题
MemoryMax 和 MemoryHigh 有什么区别?
MemoryMax 是硬限制,超过必杀;MemoryHigh 是软限制,超过会触发内存回收压力但不一定立即杀死服务。
设置限制后服务退出码是多少?
通常因 OOM 被杀的服务退出码为 137(128+9,SIGKILL),在 systemctl status 中可见。
这个限制会影响子进程吗?
会影响,systemd 服务下的所有子进程都归属于同一个 cgroups 组,共享该内存配额。
参考来源
- systemd 官方文档,systemd.resource-control 手册页,https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html
- systemd 变更日志,关于 MemoryLimit 废弃说明,https://github.com/systemd/systemd/blob/main/NEWS