最近在维护业务服务器时,遇到个头疼事儿——后台跑的Python日志归档脚本总悄悄抢占CPU和IO,导致核心交易接口偶尔出现100ms+的延迟。排查后发现,原来是这些“边角料”任务的资源优先级没管好。

今天就把压箱底的方案分享出来:在Ubuntu系统中,如何把Python程序的CPU、磁盘IO、网络优先级全拉到最低,让它安安静静当“背景板”,绝不干扰主业务。文中所有操作都以我服务器上的/home/admin/myapp/empty_20mb_file.py为例,亲测生产环境可用。

适用场景:日志处理、文件批量压缩、非实时数据同步等所有“可后台躺平”的Python任务。

一、先搞懂:Ubuntu的3种资源优先级“开关”

Ubuntu对进程资源的管控有成熟机制,不用装任何第三方工具,用好系统自带的三个“开关”就行。先过一遍基础概念,后面直接上实操。

1. CPU优先级:用nice命令“降级”

nice值是Linux管CPU优先级的老熟人了,范围从-20(最高优先级,抢资源狠角色)到19(最低优先级,佛系待命)。我们要做的就是把Python程序的nice值拉到19,让它“礼让”所有进程。

最简单的临时启动方式:

nice -n 19 python3 /home/admin/myapp/empty_20mb_file.py

2. 磁盘IO优先级:ionice设为“空闲时运行”

CPU降了还不够,有些Python脚本疯狂读写磁盘(比如我的日志脚本),照样卡主业务。这时候就得用ionice控制IO优先级。

ionice分三个等级:

  • class 1:实时IO,优先读写(绝对不能用)

  • class 2:普通IO,和主业务平等竞争(不是我们要的)

  • class 3:空闲IO,只有系统彻底没IO压力时才运行(完美匹配需求)

临时启动命令,直接指定class 3:

ionice -c3 python3 /home/admin/myapp/empty_20mb_file.py

3. 网络优先级:TOS标记“最低流量”

有些Python程序要走网络(比如下载文件),但我们不想限制它的带宽,只是让它的流量“靠后站”。这时候可以用TOS(Type of Service)标记网络包。

系统里IPTOS=0x04这个值是关键,代表“最低前景数据”,内核会自动把这类流量排在后面,而且不影响实际带宽使用——简单说就是“能跑满带宽,但不抢网速”。

二、实操:写启动脚本,整合所有优先级配置

临时启动命令适合测试,生产环境肯定要做持久化。第一步先写个启动脚本,把nice和ionice的配置整合起来,方便后续管理。

1. 创建启动脚本

在Python程序所在目录创建start_lowprio.sh脚本:

sudo nano /home/admin/myapp/start_lowprio.sh

粘贴以下内容(注意路径要和你的Python程序对应):

#!/bin/bash
# 切换到Python程序所在目录,避免相对路径报错
cd /home/admin/myapp
# 整合ionice和nice,exec让Python进程继承脚本进程属性
exec ionice -c3 nice -n 19 python3 /home/admin/myapp/empty_20mb_file.py

2. 给脚本加执行权限

这步别忘,否则脚本跑不起来:

chmod +x /home/admin/myapp/start_lowprio.sh

可以先手动测试下脚本是否正常:./start_lowprio.sh,如果Python程序能启动,说明脚本没问题。

三、关键一步:用systemd做服务,实现自动重启

脚本能跑了,但万一Python程序崩溃了怎么办?必须用systemd做成服务,配置自动重启,还要把网络优先级和资源权重加上,形成完整的“低优先级+高可用”方案。

1. 创建systemd服务文件

systemd服务文件都放在/etc/systemd/system/目录下,我们创建一个名为emptyfile.service的服务:

sudo nano /etc/systemd/system/emptyfile.service

粘贴以下配置(我标了详细注释,新手也能看懂):

[Unit]
# 服务描述,systemctl status时能看到
Description=Low Priority Python Task (empty_20mb_file)
# 网络启动后再启动该服务,避免网络依赖问题
After=network.target

[Service]
# 工作目录,和Python程序一致
WorkingDirectory=/home/admin/myapp
# 启动命令,指向我们写的脚本
ExecStart=/home/admin/myapp/start_lowprio.sh

# CPU相关配置:nice=19(最低优先级)+ CPUWeight=1(最小配额)
Nice=19
CPUWeight=1

# IO相关配置:IOWeight=1(最小IO配额),配合脚本里的ionice -c3
IOWeight=1

# 网络配置:TOS标记最低优先级流量
IPTOS=0x04

# 日志配置:避免输出塞满系统日志,统一存到journal
StandardOutput=journal
StandardError=journal

# 自动重启配置:无论退出原因,都自动重启
Restart=always
# 崩溃后5秒再重启,避免频繁重启占用资源
RestartSec=5

[Install]
# 多用户模式下启动(服务器常规模式)
WantedBy=multi-user.target

2. 核心配置说明(新手必看)

很多人配置systemd踩坑,就是没搞懂关键参数,这里单独拎出来解释:

配置项 作用 避坑点
Nice=19 CPU优先级最低,和脚本里的nice呼应 不能设成20,系统不支持
CPUWeight=1 cgroup CPU配额,1是最小值(范围1-10000) 配合Nice使用,双重保障CPU优先级
IOWeight=1 cgroup IO配额,1是最小值 必须和ionice -c3搭配,IO控制更彻底
IPTOS=0x04 网络流量标记为最低优先级 别改数值,0x04是系统标准值
Restart=always 程序崩溃、服务器重启都自动启动 生产环境必开,避免人工干预

四、启动服务+开机自启,一步到位

服务文件配置好后,执行以下命令让配置生效,这几步是systemd的常规操作,记不住可以存为备忘录。

1. 重新加载systemd配置

修改服务文件后必须执行,否则系统识别不到:


sudo systemctl daemon-reload

2. 设置开机自启

确保服务器重启后服务能自动跑起来:


sudo systemctl enable emptyfile.service

3. 启动服务并查看状态


# 启动服务
sudo systemctl start emptyfile.service

# 查看服务状态(关键,确认是否正常启动)
systemctl status emptyfile.service

如果输出里有“active (running)”和绿色圆点,说明服务启动成功;如果是红色失败,直接看下面的日志排查。

4. 常用服务命令(收藏备用)

# 停止服务
sudo systemctl stop emptyfile.service

# 重启服务
sudo systemctl restart emptyfile.service

# 禁止开机自启
sudo systemctl disable emptyfile.service

五、排错神器:查看服务日志(运维必学)

Python程序报错、服务启动失败,别瞎猜!systemd的日志全给你记下来了,用journalctl命令就能查。这是我日常排错用得最多的命令,没有之一。

1. 实时查看日志(类似tail -f)

程序运行中实时监控输出,适合调试:

journalctl -u emptyfile.service -f

2. 查看最新200行日志

避免日志刷屏,直接看最新内容:

journalctl -u emptyfile.service -f -n 200

3. 查看指定时间范围内的日志

比如查最近1小时的日志,定位历史问题:

journalctl -u emptyfile.service --since "1 hour ago"

提示:如果是Python语法错误、依赖缺失,日志里会直接显示报错信息,照着改就行。

六、验证:优先级真的生效了吗?(实测环节)

配置完不能凭感觉,必须用命令验证,确保每一项优先级都真的生效。这里需要先拿到Python程序的PID(进程ID),方法如下:

ps -ef | grep empty_20mb_file.py

输出里第一个数字就是PID,记下来备用。

1. 验证CPU优先级(Nice值)

ps -o pid,ni,cmd -p 你的PID

如果输出中“NI”列显示19,说明CPU优先级配置生效。

2. 验证IO优先级(ionice等级)

ionice -p 你的PID

输出显示“idle class”(也就是class 3),IO优先级没问题。

3. 验证网络优先级(TOS标记)

ss -tionp | grep python

在输出里找“tos 0x4”的字段,有这个就代表网络优先级标记成功。

七、总结:一套组合拳,搞定资源优先级

最后把核心配置整理成表格,方便大家收藏套用。本质上就是用“nice+ionice+IPTOS”控制三大资源,再用systemd做服务保障高可用,这套方案在我的服务器上稳定运行大半年了,从没出过资源抢占问题。

资源类型 核心配置 实现效果
CPU nice=19 + CPUWeight=1 最低优先级,不抢主业务CPU
磁盘IO ionice -c3 + IOWeight=1 系统空闲时才读写,不卡磁盘
网络 IPTOS=0x04 流量优先级最低,不占网速
高可用 systemd + Restart=always 崩溃自动重启,无需人工干预
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐