在多任务、多用户的服务器环境中,任何一个进程的失控都可能耗尽系统资源,导致其他关键服务无法正常工作。Linux 提供了一套强大的资源管理机制,核心是 cgroups(控制组) 和 命名空间,配合传统的进程优先级工具,可以对 CPU、内存、磁盘 I/O 进行精细的隔离、限制和优先级调度。现代 Linux 发行版通常已默认挂载 cgroup 文件系统,systemd 更是将其深度集成,让服务级别的资源控制变得异常简单。
1. CPU 资源控制
- 权重分配(shares):在多个 cgroup 竞争 CPU 时间时,通过
cpu.shares指定相对权重。默认值为 1024,数值越高,分得的 CPU 比例越大。这不会强制限制绝对用量,只在 CPU 繁忙时起效。 - 硬性配额(quota/period):使用 CFS(完全公平调度器)的带宽控制,可以精确限制一个 cgroup 在单位时间内能使用的 CPU 时长。例如,
cpu.cfs_period_us设为 100000(100ms),cpu.cfs_quota_us设为 50000(50ms),则该组内的进程每 100ms 最多只能使用 50ms CPU 时间,即限制到 0.5 个 CPU 核心。 - nice 值:传统工具
nice和renice可以调高或降低单个进程的优先级(-20 最高,19 最低),对非特权用户,只能调低自己进程的优先级。其作用范围有限,适合临时调整,cgroup 则更适合长期策略。
实用示例(systemd):为一个服务单元设置 CPU 限制,只需在 [Service] 段添加:
CPUQuota=50%
该服务立即被限制在全部 CPU 资源的 50% 以内,无需手动操作 cgroup 文件。
2. 内存资源限制
cgroup 的 memory 子系统可以设定硬性上限,当组内内存使用超出限制时,行为由 memory.oom_control 决定。
- 硬性限制:向
memory.limit_in_bytes写入字节数(如1G)。 - 软性限制:
memory.soft_limit_in_bytes,仅在系统内存有压力时尝试回收。 - OOM 处理:可以禁用 OOM killer,让进程分配失败,或保持开启,内核会选择进程终止。
实用示例(直接操作 cgroup 文件系统):
# 创建一个名为 myapp 的控制组
mkdir /sys/fs/cgroup/memory/myapp
# 限制最大内存使用为 512MB
echo 536870912 > /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes
# 将当前 shell 的 PID 加入该组(所有子进程都会继承)
echo $$ > /sys/fs/cgroup/memory/myapp/cgroup.procs
此时,若 shell 及子进程内存用量超过 512MB,最耗内存的进程将被 OOM killer 杀死(或依据 oom_control 行为)。
systemd 方式:在服务文件中添加 MemoryMax=512M 即可。
3. 磁盘 I/O 控制
cgroup 的 blkio(或 v2 中统一的 I/O 控制器)可以按权重或上限来限制块设备访问。
- 权重调度:
blkio.weight(默认 100),与 CPU shares 类似,在争用 I/O 时给予比例分配。 - 吞吐量/IOPS 限制:更精确的
blkio.throttle.read_bps_device、blkio.throttle.write_iops_device等,可针对特定设备(主、次设备号)设定每秒读/写字节数或操作次数的上限。 - ionice:用户空间的
ionice命令可设置单个进程的 I/O 调度类和优先级: - 实时类(1):立即访问磁盘,可能导致其他进程饥饿。
- 尽力而为类(2):默认,可设置 0-7 的优先级(0 最高)。
- 空闲类(3):仅当磁盘空闲时才进行 I/O。
实用示例(ionice):
# 以“空闲”I/O 类运行一个备份脚本,避免影响线上服务
ionice -c 3 -t 0 /path/to/backup.sh
cgroup 限制:比如限制 /dev/sda 的写速度为 10MB/s:
echo "8:0 10485760" > /sys/fs/cgroup/blkio/mygroup/blkio.throttle.write_bps_device
(8,0 是设备主次编号,可通过 lsblk 或 stat 查看)
实际场景
- 防止某个 web 应用内存泄漏导致整机崩溃:给该服务的 cgroup 设定内存上限,并开启 OOM killer,让最耗内存的进程被杀,其他服务不受影响。
- 保证数据库的 I/O 优先级:使用 ionice 将物理备份作业设为 idle 类,避免和在线事务争用磁盘。
- 多租户环境公平分配 CPU:为每个租户服务的 cgroup 设置不同的 cpu.shares,例如 VIP 租户 2048,普通租户 1024,确保在压力下 VIP 得到更多资源。
Linux 的资源控制机制已经渗透到从容器(Docker、Kubernetes)到 systemd 服务的各个层面。掌握这些基础手段,就能在资源紧张时轻松构建出健壮、隔离良好的生产环境。