答案:Linux通过cgroups限制进程资源使用,可防止资源耗尽、保障服务稳定性。具体通过挂载cgroup文件系统,创建控制组并配置CPU、内存等限制(如cpu.cfs_quota_us、memory.limit_in_bytes或cgroup v2的cpu.max、memory.max),再将进程PID写入tasks或cgroup.procs文件实现。cgroups v1为多层级结构,v2为统一层级,更推荐新系统使用。结合systemd可声明式管理资源限制,通过Service单元设置CPUQuota、MemoryLimit等参数,实现持久化、自动化配置,提升系统可靠性与可维护性。

在Linux系统中,要限制进程的资源使用,核心机制就是cgroups (control groups)。它允许我们将进程组织成不同的组,然后对这些组进行资源分配和限制,比如CPU时间、内存、磁盘I/O和网络带宽等。这就像给不同的部门划定预算,确保每个部门都在自己的“配额”内运行,避免某个部门无限制地占用公司资源。
要手动配置cgroups来限制进程资源,通常涉及以下几个步骤。这有点像在文件系统里直接操作,虽然有点底层,但能让你明白其原理。
确认cgroup文件系统已挂载: 大多数现代Linux发行版都会默认挂载cgroup文件系统。你可以通过
mount -t cgroup
mount -t cgroup2
/sys/fs/cgroup/cpu
/sys/fs/cgroup/memory
cgroup2
/sys/fs/cgroup
创建控制组: 在相应的cgroup子系统目录下创建一个目录,这个目录就代表你的控制组。 比如,要在CPU子系统下创建一个名为
my_limit_group
sudo mkdir /sys/fs/cgroup/cpu/my_limit_group
sudo mkdir /sys/fs/cgroup/memory/my_limit_group
配置资源限制: 进入你创建的控制组目录,你会看到一些文件,通过修改这些文件来设定限制。
CPU限制 (cgroup v1 示例):
cpu.cfs_period_us
cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/my_limit_group/cpu.cfs_period_us
echo 50000 > /sys/fs/cgroup/cpu/my_limit_group/cpu.cfs_quota_us
如果你只是想设置CPU份额(相对权重),可以使用
cpu.shares
echo 512 > /sys/fs/cgroup/cpu/my_limit_group/cpu.shares
内存限制 (cgroup v1 示例):
memory.limit_in_bytes
echo 536870912 > /sys/fs/cgroup/memory/my_limit_group/memory.limit_in_bytes
memory.swappiness
cgroup v2 示例 (CPU和内存): cgroup v2的配置方式略有不同,它通常在一个统一的层级下。
sudo mkdir /sys/fs/cgroup/my_limit_group
echo "+cpu +memory" > /sys/fs/cgroup/my_limit_group/cgroup.subtree_control
echo 50000 > /sys/fs/cgroup/my_limit_group/cpu.max
quota period
echo 536870912 > /sys/fs/cgroup/my_limit_group/memory.max
将进程添加到控制组: 将目标进程的PID写入到控制组目录下的
tasks
cgroup.procs
12345
echo 12345 > /sys/fs/cgroup/cpu/my_limit_group/tasks
echo 12345 > /sys/fs/cgroup/memory/my_limit_group/tasks
echo 12345 > /sys/fs/cgroup/my_limit_group/cgroup.procs
你也可以在新启动一个进程时直接将其放入某个cgroup,比如使用
cgexec
cgroup-tools
这问题,说实话,我个人在生产环境里,就遇到过因为某个日志服务突然飙升内存,直接把整个机器拖垮的惨痛教训。当时整个系统都卡死了,SSH都连不上,最后只能硬重启。所以,限制资源真的不是小题大做,它直接关系到系统的稳定性和可用性。
从更深层次看,限制资源有几个非常实际的理由:
cgroups这东西,一开始接触,v1的独立层级确实让人有点懵,感觉像是一堆独立的开关。每个控制器(CPU、内存、IO等)都有自己独立的层级结构,你可以把一个进程放在不同的控制器层级下的不同组里。这导致一个进程可能在CPU控制器下属于A组,在内存控制器下属于B组,管理起来有点混乱。
但cgroups v2出来后,那种统一管理的思路就清晰多了,虽然上手可能需要一点点适应,但长远看绝对是趋势。
cgroups v1 (传统版本):
cgroups v2 (统一版本):
cpu.max
cpu.cfs_quota_us
cpu.cfs_period_us
如何选择?
containerd
crun
说实话,手动在
/sys/fs/cgroup
Systemd通过其Service、Scope、Slice等单元类型,将进程自动归类到cgroups中,并允许你直接在单元文件中定义资源限制。
基本原理: 当你启动一个systemd服务(
.service
.service
配置示例(以一个名为 my-app.service
创建或编辑服务文件:
sudo systemctl edit --full my-app.service
添加或修改以下参数:
[Unit] Description=My Custom Application After=network.target [Service] ExecStart=/usr/local/bin/my_app_executable Restart=on-failure # 启用CPU和内存的会计功能(查看资源使用情况) CPUAccounting=true MemoryAccounting=true # CPU限制 # CPUQuota: cgroup v2 风格,限制CPU使用百分比 (20% CPU) CPUQuota=20% # CPUShares: cgroup v1 风格,相对CPU份额 (默认1024) # CPUShares=512 # 内存限制 # MemoryLimit: 内存使用上限 (512MB) MemoryLimit=512M # MemorySwapMax: 交换区使用上限 (0表示禁用交换区,防止进程使用过多交换区) MemorySwapMax=0 # I/O限制 (需要blkio控制器支持) # IOWeight: I/O相对权重 (默认1000) # IOWeight=500 # IOReadBandwidthMax=/dev/sda 10M # 限制从/dev/sda读取最大10MB/s # IOWriteBandwidthMax=/dev/sda 5M # 限制写入/dev/sda最大5MB/s [Install] WantedBy=multi-user.target
重新加载systemd配置并启动服务:
sudo systemctl daemon-reload
sudo systemctl start my-app.service
Systemd管理cgroups的优势:
/sys/fs/cgroup
systemd-cgtop
systemctl status my-app.service
Slice
Scope
Slice
Slice
利用systemd来管理cgroups,是现代Linux系统上最推荐的做法,它不仅简化了操作,还提高了系统的可维护性和可靠性。
以上就是如何在Linux中限制进程资源 Linux cgroups配置方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号