
我在香港裸金属服务器上,部署了多套业务系统:一个高并发的FastAPI服务、一个异步任务Worker,以及一个Redis缓存实例。起初我图省事,所有服务都用systemd启动,默认跑在相同的CGroup层级。但没多久就发现,任务Worker在高负载场景下疯狂占用CPU和磁盘IO,严重影响了FastAPI接口响应时间,甚至让Redis延迟暴增,出现客户端超时。
这个问题让我意识到,仅靠进程优先级调度(nice/ionice)远远不够。我决定深入使用systemd原生支持的资源限制机制,分别对CPU、IO、内存进行精细化控制,建立一个具备隔离性的systemd服务调度模型。
下文将结合实战环境,从零配置完整的systemd级资源配额方案。
一、为什么选择systemd控制资源?
在Linux内核中,CGroup(Control Groups)已经成为资源隔离的主力机制,而systemd正是对其进行了封装,并集成了资源控制的统一配置接口:
- 使用CPUQuota/CPUShares限制服务的CPU占用比;
- 使用IOWeight或IOReadBandwidthMax等限制磁盘IO;
- 默认支持cgroup v2体系,可和cgroup.slice结构协同管理多服务。
对我来说,最大的优势在于无需引入额外组件,只需要配置.service文件即可落地生产环境。
二、环境准备:确认CGroup版本
我的香港物理机运行的是CentOS Stream 9,默认启用了cgroup v2。可以通过以下命令确认:
cat /sys/fs/cgroup/cgroup.controllers
如果能看到cpu, io, memory 等控制器,说明已启用v2。对于RHEL/CentOS 7还需手动配置GRUB启用v2模式。
三、资源隔离目标与限制方案
| 服务名称 | 类型 | 限制目标 | 限制方式 |
|---|---|---|---|
| fastapi-api | 高优先级接口 | 保证CPU/IO响应优先 | CPUWeight=900, IOWeight=900 |
| worker-tasks | 异步Worker | 限制抢占资源 | CPUWeight=100, IOWeight=100 |
| redis-cache | 缓存服务 | 保证低延迟IO访问 | IOReadBandwidthMax, IOWriteBandwidthMax |
四、配置 systemd service 控制资源配额
4.1 配置 FastAPI 服务资源权重
编辑 /etc/systemd/system/fastapi-api.service,添加以下内容:
[Service]
CPUWeight=900
IOWeight=900
说明:CPUWeight是相对值(范围1–10000),数值越高获得越多的调度时间片。IOWeight同理。
4.2 配置 Worker 异步任务服务
[Service]
CPUWeight=100
IOWeight=100
我们也可以进一步加上CPUQuota,比如限制最多只能使用50%核心资源:
CPUQuota=50%
4.3 配置 Redis 实例的IO带宽
假设Redis运行在/dev/nvme0n1盘上:
cat /sys/block/nvme0n1/dev
假设输出为 259:0,那么:
[Service]
IOReadBandwidthMax=259:0 10M
IOWriteBandwidthMax=259:0 10M
表示Redis最多每秒只能读写10MB,避免它在flush或AOF rewrite时冲击磁盘。
五、创建专属Slice进行统一资源池管理
为了便于管理,我将这些服务统一纳入一个自定义Slice,比如:biz.slice
编辑 /etc/systemd/system/biz.slice:
[Slice]
CPUAccounting=yes
IOAccounting=yes
CPUQuota=90%
然后在每个服务的.service文件中添加:
[Service]
Slice=biz.slice
这样能确保业务服务共用统一的资源池,且能避免系统服务(如system.slice)被影响。
六、重载systemd并观察效果
systemctl daemon-reexec
systemctl daemon-reload
systemctl restart fastapi-api.service
systemctl restart worker-tasks.service
systemctl restart redis-cache.service
确认服务是否绑定了正确的资源控制器:
systemctl status fastapi-api.service
systemd-cgls
systemd-cgtop
也可以直接通过cgroup文件系统查看实时指标:
cat /sys/fs/cgroup/biz.slice/fastapi-api.service/cpu.stat
cat /sys/fs/cgroup/biz.slice/worker-tasks.service/io.stat
七、效果评估与后续调优
部署完成后,我通过压力测试观察FastAPI服务在高负载下依然能保持响应时延<50ms,Redis未再出现flush拥塞。Worker虽然执行时间略有拉长,但不会再干扰主业务。整体资源利用率更加平滑,load average不再出现极端波峰。
后续还可结合MemoryMax、TasksMax进一步限制内存和进程数,结合oomd策略强化异常服务的kill规则。
在多业务混合部署的香港物理机上,若不进行资源隔离,很容易出现“强者恒强”的调度问题。通过构建基于systemd的CGroup v2资源配额体系,我实现了精细、动态、稳定的资源分配策略,保障了关键服务的性能底线。相比传统容器方案,这种方法在物理机裸部署场景下更具通用性和可控性,是我在裸金属环境中推荐的首选方案之一。











