核心在于区分场景:临时压制用cpulimit(基于sigstop/sigcont信号,快速但有抖动);长期稳定控制必须用cgroups v2+systemd cpuquota(内核级配额,持久、精准、跨fork生效)。

限制单个进程的 CPU 使用率,核心在于区分“临时压制”和“长期稳定控制”两类场景。前者用 cpulimit 快速见效;后者必须依赖内核原生机制——cgroups v2 + systemd,否则无法真正持久、精准、跨 fork 生效。
临时限制:用 cpulimit 快速干预
适合调试、应急降载、防程序失控,不依赖重启或服务重配。
-
安装简单:Ubuntu/Debian 执行
sudo apt install cpulimit;RHEL/CentOS 8+ 用sudo dnf install cpulimit;若无包,可编译安装(源码见 GitHub cpulimit 项目) -
按 PID 限速最可靠:先查 PID(如
pidof nginx或ps aux | grep python),再运行cpulimit -p 1234 -l 40 -b(-l 是单核百分比,双核机器设 80 才≈总 CPU 40%) -
按名称或路径更灵活:用
-e python3或-P /usr/bin/node,加-i可联动子进程,加-z让 cpulimit 在目标退出后自动终止 -
注意局限:它靠反复发
SIGSTOP/SIGCONT暂停恢复进程,不是内核调度干预,存在抖动、不平均、多核负载不均衡问题;被seccomp或禁用ptrace的容器中会直接失败
长期服务:用 systemd CPUQuota 内核级配额
适用于由 systemd 管理的守护进程(如 nginx、redis、自定义 service),限制写入 unit 文件,随系统启动生效,稳定且可热更新。
-
编辑服务配置:运行
sudo systemctl edit nginx.service,输入:[Service]CPUQuota=60% -
立即启用:执行
sudo systemctl daemon-reload && sudo systemctl restart nginx.service -
验证是否生效:查看
cat /sys/fs/cgroup/system.slice/nginx.service/cpu.max,应显示类似60000 100000(即每 100ms 周期最多用 60ms) -
关键前提:系统需启用 cgroups v2(检查
stat -fc %t /sys/fs/cgroup输出是否为cgroup2fs),且内核编译选项CONFIG_CFS_BANDWIDTH=y已开启(现代发行版默认满足)
手动 cgroups v2:精细控制与脚本化部署
当需要绕过 systemd、或集成进自动化脚本时,可直接操作 cgroups v2 接口。
-
创建并配置 cgroup:
sudo mkdir -p /sys/fs/cgroup/myappecho "60000 100000" | sudo tee /sys/fs/cgroup/myapp/cpu.max -
把进程加入该组:
echo $PID | sudo tee /sys/fs/cgroup/myapp/cgroup.procs -
启动新进程时直接绑定:
sudo cgexec -g cpu:/myapp /path/to/app -
权限注意:非 root 用户需有
CAP_SYS_ADMIN或所在 cgroup 目录可写(ls -ld /sys/fs/cgroup/myapp中含w)
别踩坑:常见误区澄清
- nice/renice 不是 CPU 限制:只调整调度权重,不设时间上限;在空闲系统里,高 nice 值进程仍可跑满 CPU
-
cpulimit 不能按用户限 CPU:它没有用户维度参数;想控某用户所有进程,需配合
pgrep -u username批量获取 PID 后逐个调用,属快照式操作,非实时防护 -
限制值单位易错:cpulimit 的
-l是“单核百分比”,systemd 的CPUQuota=50%是“总 CPU 百分比”;cgroups v2 的cpu.max单位是微秒(us)











