compose 资源限制是什么
在 Compose 文件里可以通过 deploy.resources.limits 为服务声明 CPU 与内存上限,docker compose 在本地运行时会把这些限制应用到容器上。它对应的是一套以 deploy 为根的字段结构,最初为集群编排设计,现在本地运行也支持其中一部分。旧式字段 cpus、mem_limit 仍在生效,但已经不再是推荐写法,新项目应统一用新的结构。
基本信息
| 推荐写法 | deploy.resources.limits.cpus 与 .memory |
|---|---|
| 预留写法 | deploy.resources.reservations.memory(软性预留) |
| 旧式字段 | cpus、mem_limit、mem_reservation(仍可用,不推荐扩展) |
| 取值范围 | cpus 支持小数如 "1.5";memory 支持 512M、1g 等后缀 |
| 生效条件 | docker compose up 时应用;集群模式由调度器解释 |
| 验证方式 | docker stats 与 docker inspect 的 HostConfig 字段 |
典型使用场景
- 单机多服务部署时防止某个服务吃满内存拖垮整台机器
- 给 Java 等内存敏感服务设置上限并同步调整堆参数
- 压测环境模拟生产资源约束,提前暴露容量问题
- 给批处理任务限 CPU,避免影响在线服务
- 排查反复重启:先确认是否触发了资源限制
声明限制
声明限制
services:
api:
image: app/api:1.4.2
deploy:
resources:
limits:
cpus: "1.5" # 最多使用 1.5 个核的算力
memory: 512M # 超过上限会被内核终止
reservations:
memory: 256M # 预留提示,单机模式下不强制
batch:
image: app/batch:1.0
cpus: 0.5 # 旧式写法,兼容老文件
mem_limit: 256m验证限额是否生效
验证限额是否生效
# 先渲染配置,确认字段被正确解析
docker compose config | sed -n '1,60p'
# 运行后核对容器实际限额:Memory 与 NanoCpus 是引擎侧的真实取值
docker inspect -f '{{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}' myproj-api-1
# 实时观察用量与限额对照
docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}' myproj-api-1
# 若出现过被杀:看退出码与 OOM 标记
docker inspect -f 'exit={{.State.ExitCode}} oom={{.State.OOMKilled}}' myproj-api-1字段与后果对照
| 字段 | 含义 | 设置不当的后果 |
|---|---|---|
| cpus | CPU 配额上限 | 过低时任务排队变慢、超时增多 |
| memory | 内存硬上限 | 过低触发 OOM 终止,容器反复重启 |
| reservations.memory | 预留提示 | 单机模式不强制,容易误以为已保障 |
| mem_limit | 旧的等价字段 | 与新字段混用时行为难以判断 |
| cpus(旧) | 旧的 CPU 上限 | 数值写法与限制单位容易混淆 |
内存上限对按整机内存自动计算堆大小的运行时不友好:Java、Node 之类的进程可能仍按宿主总内存推导堆参数,结果申请超过上限被终止。限制内存时要把应用自身的堆参数一起调小。
reservations 是预留提示而非硬保障。单机模式下它不会为你保留资源,真正的约束只有 limits;需要资源保障要靠调度平台。