性能管理只有两步——先量,再调;调的抓手是进程优先级,而优先级里最容易记错的两条是:普通用户只能调高不能调低,而且它只在有竞争时才起作用。
9-7 讲的是怎么把数据采上来,这一节讲采到数据之后怎么动手。它是 9-7 的直接延续,也是全章唯一一节需要动手敲命令的内容。教材 9-8 的并列关键词是【检查使用率、修改进程的优先级】。
一、先量,再调
性能管理的顺序不能颠倒。先量清楚瓶颈在哪,再动手调。 测的顺序基本固定:
- 看整体负载——
uptime看系统负载,vmstat 1看 CPU 的构成。 - 找头号消耗者——
ps aux --sort=-%cpu | head或htop。 - 看 CPU 时间花在哪——用户态(us)、系统态(sy)、等待 I/O(wa)。
wa高说明瓶颈在磁盘,不在 CPU。 - 看磁盘——
iostat -x 1,看利用率与延迟。
这一步最常被跳过的判断是:CPU 满不等于 CPU 不够。
如果 wa 很高,说明 CPU 是在等磁盘,这时候加 CPU 一点用都没有,
该换的是存储。调优的第一个动作永远是确认瓶颈真的在你要调的那个地方。
二、调优先级的工具,各有各的分工
确认瓶颈之后,调的手段有好几种,它们管的事情完全不同:
nice——启动进程的时候给个优先级。适合提前知道【这是个后台活】。renice——改一个已经在跑的进程的优先级。用于事后补救。cgroups/CPUQuota——给服务设硬上限,是内核强制的。systemd单元文件——把优先级写成配置,重启后仍然生效。ionice——调的是磁盘读写优先级,对付备份、压缩这类活。taskset——把进程绑到指定的 CPU 核上,减少来回跳的开销。
一个务实的习惯转变值得单独说:从【烦了敲一条 renice】,改成【把策略写进 systemd 单元文件】。 前者只有你记得,后者重启之后还在,而且能被别人 review。
nice 和 cgroups 的区别也要分清:nice 只是把尺子(相对份额),cgroups 才是把刀(绝对上限)。
要卡死一条线,只能用后者。
三、nice 值的两条规矩
nice 的取值范围是 −20 到 19,数字越小越优先(默认是 0)。
这里有两条最容易记错、也最容易踩坑的规矩:
- 普通用户只能把优先级调低(把值调大),不能调高。 想给一个进程更高优先,需要管理员权限——这是故意的, 因为随便提权会饿死别的进程,把整台机器拖垮。
nice只在 CPU 有竞争的时候才起作用。 机器闲着的时候,所有进程都能拿到资源,改不改没有任何区别。 所以【我设了 nice 但没感觉变快】是正常的——你缺的是竞争,不是设置。
还有两个常见误区:
nice只管 CPU,不管内存和磁盘。磁盘拖慢要去动ionice。- 改了父进程不等于改了子进程。真正吃 CPU 的往往是子进程, 要按实际消耗去 renice(一次可以带上好几个 PID),别只改顶层的那个。
另外提醒一句:nice -10 cmd 这种写法有歧义,规范写法是 nice -n -10 cmd。
脚本里尤其要注意——歧义写法在不同实现下行为不一样。
四、落到场景:惯用的配法
把上面这些拼起来,就是几种常见的配法:
- 数据库服务器——主进程给高优先级,备份任务给低优先级; 查询不能被备份拖慢。
- Web 应用——Nginx 和 PHP-FPM 保持默认(nice 0), 它们本来就该及时响应,不需要特殊照顾。
- 队列消费进程——给低优先级(比如 10 到 19);晚几秒处理没人察觉。
- 大文件备份、解压、索引——低 CPU 优先级加低磁盘优先级, 把磁盘留给在线业务。
这里有一条不成文的经验值得记住:频繁改优先级本身就是信号。
如果天天要 renice,说明这台机器的容量已经不够了——
该做的是加资源或者分机器,而不是继续在优先级上找平衡。
最后补一句:激进地给某个进程设很低的 nice 值(比如 −20),会让别的进程明显变卡。 日常调优的原则是小幅调、测完再看, 而不是一次调到底。
五、动手 Demo:把优先级与巡检口径算一遍
优先级调优里的几个数,其实都能算成更直观的说法:
print(" nice 范围 -20 ~ 19,跨 %d 档" % (19 - (-20)))
print(" 默认 0 到最低 19,还有 %d 档可让步" % (19 - 0))
print(" CPU 告警阈值 90%%,留 %.0f 个百分点的余量" % (100 - 90))
print(" 每 5 分钟巡检,一天 %d 次" % (24 * 60 // 5))
print(" 把队列进程设成 nice 10:它只在有竞争时才让路")
实跑输出:
--------------------------------------------------------------------
CPU 满了,先动谁
--------------------------------------------------------------------
服务器的性能管理只有两步:先量,再调。量的是各种使用率,
调的是各进程占资源的优先级。这里说的优先级,主要是 CPU 上的分寸。
Linux 里调优先级用的还是那几个老命令,但 2026 年的习惯变了:
工具 作用 什么时候用
-----------------------------------------------------------------------
nice 启动时给个优先级 提前知道这是个后台活
renice 改已在跑进程的优先级 发现某个进程霸占 CPU
cgroups / CPUQuota 给服务设硬上限 要保证不能超过某条线
systemd 单元文件 把优先级写成配置 服务重启后仍然生效
ionice 调的是磁盘读写优先级 备份、同步把磁盘拖慢时
taskset 绑定到指定 CPU 核 要减少线程来回跳的开销
-----------------------------------------------------------------------
nice 值的范围是 −20 到 19,数字越小越优先。有两条规矩容易踩:
要点 说明
--------------------------------------------------------------
普通用户只能调高不能调低 把优先级往上提需要管理员权限
nice 只在有竞争时才起作用 机器闲着的时候,改不改都一样快
它只管 CPU,不管内存和磁盘 磁盘拖慢要去动 ionice
改父进程不等于改子进程 真正吃 CPU 的往往是子进程
--------------------------------------------------------------
落到具体场景,惯用的配法是这样的:
场景 做法 为什么
-------------------------------------------------------------------------
数据库服务器 主进程给高优先,备份给低优先 查询不能被备份拖慢
Web 应用 Nginx 与 PHP-FPM 保持默认 它本身就该及时响应
队列消费进程 给低优先 晚几秒处理没人察觉
大文件备份、解压 低优先 + 低磁盘优先 把磁盘留给在线业务
-------------------------------------------------------------------------
小算例:把队列进程设成 nice 10,它和默认的 Web 进程抢 CPU 时,
注意这不是对半分——nice 差 10 通常意味着 Web 进程能拿到绝大部分时间片。
nice 是把尺子,不是把刀;要卡死上限得用 cgroups 的 CPUQuota。
还有一个不成文的经验:频繁改优先级本身就是信号。如果天天要 renice,
说明这台机器的容量已经不够,该加资源或者该分机器了。
第一行的 39 档,说明 nice 是个粗颗粒的旋钮,不是精密仪器。 第三行的 10 个百分点余量,是留给突发流量的缓冲——阈值不是越贴越好。 最该记住的还是最后一行那句话:nice 只在有竞争时才起作用。 没有竞争的时候,你怎么调都测不出差别,会误以为【这个参数没用】。
30 秒实验
- 在你的电脑上跑一个吃 CPU 的任务,用任务管理器把它的优先级调低,看看界面是不是更流畅了。
- 在 Linux 上敲
nice -n 10 sleep 100 &,再用ps -o pid,ni,cmd看看它的 nice 值。 - 敲一次
uptime,看那三个数字(1、5、15 分钟负载),和你机器的核数对比一下。
常见误区
- 错误:CPU 使用率高就要加 CPU。——纠正:先看
wa(等待 I/O);wa高说明瓶颈在磁盘,加 CPU 一点用都没有。 - 错误:调了 nice 就能让程序变快。——纠正:nice 只在有 CPU 竞争时才起作用;机器闲着的时候改不改一个样。
- 错误:nice 能限制一个进程最多用多少 CPU。——纠正:nice 只是相对份额(尺子),要卡死上限得用 cgroups 的 CPUQuota(刀)。
自测三问(点开对答案)
1. 性能管理的第一步是什么? —— **先量,再调。** 而且要先确认瓶颈真的在你要调的地方——比如 `wa` 高说明瓶颈是磁盘,加 CPU 没用。 2. nice 和 cgroups 的本质区别是什么? —— **nice 是相对份额(尺子),只在有竞争时起作用;cgroups 的 CPUQuota 是内核强制的绝对上限(刀)。** 要卡死一条线只能用后者。 3. 为什么普通用户不能把 nice 值调小(提权)? —— **因为随便提权会饿死别的进程,把整台机器拖垮**;提权需要管理员权限,这是故意的限制。- ☐ 下一节(9-9 应对故障的机制:容错系统、热备份、冷备份)
相关笔记
- 系统运行后的管理 —— 上一节把数据采上来,这一节动手调
- 应对故障的机制 —— 调优解决的是【慢】,下一节讲【坏了】
- 性能与更新(性能管理、WSUS、故障命令) —— 性能管理在服务器课里的框架
- 服务器处理与高速化处理(活动监视服务器) —— 监视服务器本身的做法
- 负载的分散 —— 加机器之外的另一种解法
- 🕸️ Web技术原理 · 索引