凌晨两点被电话叫醒,一上线,用户已经在群里炸了锅——页面转圈、接口超时、登录都卡成幻灯片。我先是下意识敲了uptime、free -h、top,然后一路查下去,最后定位到系统日志把磁盘 I/O 打满了。事后复盘,我最大的感触不是排查技术有多难,而是如果我平时能把 Linux 系统监控这套东西真正落到细处,那晚根本不用折腾到天亮。
这篇文章就是基于这类实战场景写的。我不会只丢给你一串 Linux 常用命令,而是把系统监控里最值得关注的指标、我日常排查时用的命令组合、从手动到自动的监控方案,以及一次完整的问题定位过程,都摊开来说清楚。适合刚接触 Linux 运维的新手、自己跑 VPS 的个人开发者、以及正准备给生产环境搭监控体系的同学。你不需要先把所有工具都学会,跟着思路走一遍,至少能知道“服务器出问题时,下一步该敲什么”。
1. 系统监控的核心是这些指标,理清它们比记命令更重要
很多新手学监控,第一件事就是背命令,结果遇到问题还是手忙脚乱。原因很简单:命令是武器,但你要先知道“敌人”是谁。Linux 系统监控的实质,是盯住 CPU、内存、磁盘、网络、硬件健康这几类资源的状态,并且理解每个指标背后对应的业务影响。
1.1 负载均值:三个数字别只看大小
uptime会输出一个很显眼的数字:load average: 3.42, 2.87, 2.61。这三个数分别代表过去 1 分钟、5 分钟、15 分钟的系统平均负载。很多人看到负载超过 1 就紧张,其实这个数字要除以 CPU 核心数才有意义。
举个例子:一台 4 核机器,负载 4.0 意味着每个核都刚好跑满;负载 2.0 时还有一半算力空闲。反过来,如果 1 分钟负载很高但 15 分钟负载很低,说明是瞬时冲高,可能是定时任务或突发流量;如果三个数都持续走高,那就要认真对待了。
更隐蔽的情况是:负载高但 CPU 使用率不高。这往往不是 CPU 不够用,而是大量任务阻塞在磁盘 I/O、锁等待或内存换页上。只看负载不看上下文,很容易把问题带偏。我自己的习惯是,看到负载高,第一反应不是加 CPU,而是先跑一个vmstat看看到底是r(运行队列)在涨,还是wa(I/O 等待)在涨。
1.2 内存:free输出里的available才是真正能用的数
内存监控最容易犯的错,是把free命令里的free列当成剩余内存。Linux 内核有个特点,它会尽量用空闲内存做文件缓存(buff/cache),所以free列数值很小并不代表内存不够。
正确的做法是看available列,这个值是系统估算出来的“在不触发 swap 的情况下,还能分配给新进程的内存”。free -h输出大致是这样:
total used free shared buff/cache available Mem: 15Gi 2.1Gi 9.3Gi 118Mi 4.1Gi 12Gi Swap: 2.0Gi 0B 2.0Gi假定 total 15G,used 只有 2.1G,free 有 9.3G,available 却显示 12G。这里 buff/cache 占了 4.1G,但内核可以在需要时回收它,所以 available 比 free 大是正常的。真正危险的信号是 available 持续偏低、swap 开始增长、然后si/so不断有换页动作,这种时候业务会明显变卡。
1.3 磁盘:容量之外,I/O 延迟才是业务的隐形杀手
监控磁盘只看df -h空间,说明你还在第一层。空间满当然重要,但线上更常见的问题是:磁盘还有大量剩余空间,I/O 却已经忙不过来。
磁盘 I/O 的核心体现是iostat里的%util、await和aqu-sz。%util接近 100% 说明磁盘设备已经很忙了,但要注意,对 SSD 来说 100% util 并不一定代表性能到顶,很多 SSD 可以并行处理多队列;await是平均 I/O 请求处理耗时,包括排队和服务时间,这个数字超过几十毫秒就要留意了。
我遇到过最典型的场景:数据库服务器数据盘负载不高,但系统盘%util持续 90% 以上,后来发现是应用把日志写到了系统盘,日志量一大,系统盘直接成为瓶颈。所以磁盘监控要分设备看,系统盘、数据盘、日志盘单独观察,别混在一起。
1.4 网络与连接数:延迟、丢包和端口耗尽
网络监控不仅仅是看带宽跑满没有。对于提供服务的服务器,更关键的是连接状态分布和丢包率。
ss -s可以快速看到 TCP 连接总数和各状态统计。如果TIME_WAIT连接数量异常多,会影响新连接的建立,因为每个连接都需要本地端口,超过net.ipv4.ip_local_port_range的范围后就会出现Cannot assign requested address。这类问题用ss -s一眼就能看出来。
另外,延迟和丢包要看ping和mtr。ping看基础的连通性和 RTT,mtr能逐跳查看哪一跳在丢包。如果客户端反馈“慢”,但服务器本机 CPU、内存、磁盘都正常,网络层的排查就必须跟上。
1.5 硬件温度:性能衰减往往比蓝屏更早出现
服务器长期高温不会立刻宕机,但 CPU 会主动降频保护自己,性能悄悄下滑。这种现象在物理机上很常见,尤其是夏季机房制冷不足或风扇积灰。
Linux 下用lm-sensors读取温度:
sudo apt install lm-sensors sudo sensors-detect sensors输出里会包含 CPU 各核心温度、主板温度、风扇转速。如果发现 CPU 温度长期高于 85℃,就要检查散热和机房空调了。监控温度不一定非要做成复杂平台,定时采样记录日志,配合告警也能起到效果。
2. 一套命令组合拳,覆盖 90% 的日常排查
指标理清楚之后,命令才能派上用场。下面这套组合是我在实际工作中反复用的,几乎每个场景都能覆盖。
2.1 top / htop:进入任意一台机器的第一件事
top是 Linux 运维的基本功。进入交互界面后,我建议先记住几个按键:
P:按 CPU 使用率降序排列M:按内存使用率降序排列1:展开显示每个逻辑 CPU 的使用情况c:显示完整命令行
默认的按 CPU 排序适合找 CPU 密集进程,但如果你想看谁吃内存最多,按M更直观。top里还有一个关键信息是zombie僵尸进程,如果数量持续增长,说明父进程没有正确回收子进程,应用代码有问题。
htop是top的增强版,彩色显示,支持鼠标操作,F6可以选择排序字段,F9直接发信号给进程。我个人在排查时更喜欢htop,因为它把 CPU、内存、Swap 的负载条放一起,视觉上一眼就能看出资源分布。
2.2 vmstat:一条命令看到系统整体状态
vmstat是我最推荐的第二把武器。用法通常是:
vmstat 2 10表示每 2 秒采样一次,共 10 次。输出关键字段:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 951120 1452 305860 0 0 1 2 1020 2400 8 2 88 2 0排查思路是:先看r(运行队列)是不是大于 CPU 核数,如果长期大于核数,说明 CPU 饱和;再看b(阻塞进程数)是不是在涨,如果 b 高并且wa高,基本可以确定 I/O 有瓶颈。si/so是 swap 换入换出,一旦持续非零,内存很可能不够了。cs是上下文切换,过高可能和频繁锁竞争或线程太多有关。
2.3 iostat 与 sar:把磁盘细节和历史数据盘活
iostat -x 1用于监控磁盘 I/O 细节,-x展开更多扩展统计:
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz %util vda 2.30 12.50 10.5 150.2 0.00 0.00 0.00 0.00 3.20 18.60 0.20 18.4观察r_await/w_await与aqu-sz(平均队列长度)。如果aqu-sz持续大于设备并发能力,说明请求在排队,磁盘响应变慢。%util结合队列长度看,比单看%util更可靠。
sar属于 sysstat 包,它能把历史数据落盘,以便事后回放。默认采集可能没开启,需要确保/etc/cron.d/sysstat里的任务在运行,然后通过sar -q看历史负载、sar -r看历史内存、sar -d看历史磁盘。没有历史数据的监控,等于只带了手电筒却没有内存卡。
2.4 ss、iftop、nload:网络排查三件套
查端口和连接数,用ss而不是旧的netstat:
ss -tulnp # 查看所有监听端口 ss -s # 汇总连接状态 ss -t state established # 查看已建立连接-t看 TCP,-u看 UDP,-l只看监听,-n不做反解,-p显示进程。定位“谁在占用 8080 端口”这类问题,就用ss -tulnp | grep 8080。
实时流量工具,iftop可以按连接查看流量:
iftop -i eth0 -n -P-P会显示端口,方便看出具体是哪个服务在消耗流量。nload则更擅长看总入/总出带宽,适合判断带宽是否跑满。
2.5 dstat 与 perf:站在更高维度的补充工具
如果你嫌vmstat、iostat分开看麻烦,可以试试dstat:
dstat -cdngy 2一次输出 CPU、磁盘、网络、内存、系统负载。它是 Python 写的,很多发行版默认没装,apt install dstat或yum install dstat即可。它适合临时把多维度指标同时放到一个屏幕上观察。
perf top则是面向性能优化的进阶工具,可以直接看到内核和用户态的热点函数。比如 CPU 占用高但找不到是哪个进程或哪个系统调用引起的,perf top能告诉你问题发生在copy_page_range还是某个驱动函数上。这个工具对普通运维可能有点深,但值得知道它的存在。
3. 从命令到平台:给服务器装一套能长期看的监控
命令适合临时排查,但生产环境不能老是靠人肉盯着。于是我们需要监控平台。
3.1 先别急着上全家桶,评估自己的场景
一谈到监控平台,很多人直接想到 Prometheus、Zabbix、ELK。但如果你只有两三台服务器,直接搭一套完整的 Prometheus+Grafana+Alertmanager 其实有点技术债:配置项多、组件多、维护成本不小。
我个人建议按场景选择:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 个人 VPS / 三四台以内 | Netdata | 安装简单,自带图表,零配置 |
| 混合环境、需要统一收集 | Prometheus + node_exporter + Grafana | 生态成熟,可扩展,查询灵活 |
| 已有复杂 ITIL 流程 | Zabbix | 自带告警、报表、模板体系成熟 |
| 需要收集业务日志并监控 | Loki / ELK | 日志和指标分开处理,但都可以和 Grafana 结合 |
3.2 Netdata:最适合个人和小团队的即时监控
Netdata 的安装真的非常无脑:
curl -Ss https://get.netdata.cloud/kickstart.sh | sh装完后打开http://你的IP:19999,能看到 CPU、内存、磁盘、网络、进程等几百张实时图表。它对新人友好在哪?它把很多指标换算成了人类能读懂的样子,比如 CPU 频率、缓存命中率、上下文切换速率,不用你手动敲命令去猜。
我用它最舒服的场景是:给客户演示“系统当前负载很高”的时候,直接打开一个面板,指着曲线说“你看,这里 I/O 明显上去了”,比一堆命令输出直观得多。Netdata 资源占用很低,官方说空闲时只占几 MB 内存,很适合个人服务器。
3.3 Prometheus + node_exporter + Grafana:通用组合的搭建要点
这套组合现在是主流,但很多人第一次搭时会绕弯。我按最小可用方案来说明。
架构上,node_exporter负责采集 Linux 系统指标并通过 HTTP 暴露;Prometheus 定时去抓取并存储;Grafana 负责把 Prometheus 数据画成图表。
第一步,安装node_exporter,它默认监听9100端口:
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz tar xvf node_exporter-1.8.2.linux-amd64.tar.gz cd node_exporter-1.8.2.linux-amd64 ./node_exporter第二步,配置 Prometheus,修改prometheus.yml的scrape_configs:
scrape_configs: - job_name: 'node' static_configs: - targets: ['192.168.1.10:9100']启动 Prometheus 后,可以在http://你的IP:9090/targets里确认 target 是 UP 状态。
第三步,Grafana 添加 Prometheus 数据源,导入官方仪表盘 ID1860(适用于 node_exporter),就能看到丰富的系统监控面板。
这套方案的价值在于数据模型统一。所有机器指标都是带标签的时间序列,你可以轻松写 PromQL 做聚合,比如“所有 Web 服务器的平均 CPU”,一条查询就能完成。
3.4 告警配置:让监控在出问题时主动找到你
监控的意义在于出问题前提醒你。Prometheus 的告警规则和 Alertmanager 配合很常见。比如磁盘使用率超过 90% 时告警:
groups: - name: node_alerts rules: - alert: DiskUsageHigh expr: (node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes * 100 > 90 for: 5m labels: severity: warning annotations: summary: "磁盘使用率过高" description: "实例 {{ $labels.instance }},当前磁盘使用率超过 90%(持续 5 分钟)"这个规则里for: 5m很关键,它表示只有当阈值持续 5 分钟时才触发,能过滤掉很多瞬时抖动。Alertmanager 再配置一个 webhook 推到钉钉、企业微信或 Slack,告警就算闭环了。
告警另一个要点是聚合与去重。别每台机器单独刷屏,要按服务、按故障域分组。Alertmanager 里的group_by、group_wait和repeat_interval就是干这个的,默认group_wait设置为 30 秒比较合适。
4. 一次真实排查:响应变慢的服务器,监控数据如何一步步定位根因
这部分我想完整复盘一次线上事故,看命令和指标是如何配合的。
4.1 表象:负载 5.0,但 CPU 使用率只有 20%
当时业务反馈:上传文件后,前端处理速度特别慢。我登上去先执行:
uptime topuptime显示 load average 4.8,机器共 4 核,负载已经超过核数。但top里 CPU 的us只有 15%,sy5%,id却高达 80%。CPU 明明很闲,负载却这么高,问题几乎不在计算能力。
4.2 定位:vmstat 里的 wa 和 iostat 的队列长度对上了号
我继续跑:
vmstat 1 5 iostat -x 1 5vmstat中wa平均在 55% 左右,b(阻塞进程数)经常大于 2,说明大量进程在等 I/O。iostat显示vdb这块盘的%util到了 99%,aqu-sz一直在 8 以上,w_await高达 120 毫秒。到这里,瓶颈已经锁定在磁盘写入上,而且不是系统盘,是专门的数据盘。
4.3 揪出元凶:pidstat 拿到进程号,lsof 定位到文件
锁定磁盘层后,还需要知道是哪个进程在疯狂写盘。此时用pidstat -d 1看每个进程的磁盘读写速率:
pidstat -d 1 5输出片段:
14:23:01 PID kB_rd/s kB_wr/s kB_ccwr/s Command 14:23:02 1234 0.00 45000.00 0.00 java一个 Java 进程每秒写 45MB,明显不正常。继续用lsof -p 1234 | grep -E '\.log|\.out'找到它打开的日志文件路径,发现是某个中间件把 DEBUG 级日志全部输出,并且没有轮转,单个日志文件已经涨到几 GB,应用每打一条日志都要触发文件系统开销,磁盘队列自然就爆了。
4.4 处理与复盘:降日志、加轮转、查 inode
处理分了两步:第一,保留现场并立刻把日志级别调到 WARN,恢复业务;第二,写日志轮转配置,避免单文件无限增大。
但复盘时又发现一个潜在风险:这台机器/分区的 inode 使用率已经 90% 多,因为大量小文件堆积。df -i看到的结果是即使空间还有,inode 满了同样无法创建文件。这个隐患平时不显眼,一次日志乱写就可能被引爆。
那次之后,我把磁盘监控分区拆细了:系统盘看空间和 inode,数据盘关注 I/O 延迟,并在监控平台加了一个“日志目录写入速率”的视图,防止类似事件再悄悄发生。
5. 监控这条路,我不想你重复踩的坑
最后聊聊我在折腾监控过程中积累的几个教训。
5.1 数字采集到了,不等于看懂了
最典型的例子是load average。如果你只盯着数字超过核数就报警,很可能误报。高负载可能来自 I/O、内存换页或锁等待,不一定代表 CPU 繁忙。养成“多指标交叉验证”的习惯,看到负载高,就顺手看一眼 CPU 的us/sy/id/wa、内存 swap、磁盘队列,才能得出正确结论。
5.2 告警阈值拍脑袋,不如先观察基线
很多人刚搭好监控平台,就急着把所有规则加上,然后被一堆噪音告警烦到关掉。更好的做法是先跑两周基线,看正常业务的 CPU 均值、峰值、磁盘使用率和网络流量,再根据 95 分位加上一定裕量设定阈值。比如业务平时 CPU 是 30%,报警阈值设为 75% 就比 50% 更合理,避免大促或高峰时误报。
5.3 监控系统本身也是需要运维的
监控机器一旦挂了,你根本不知道系统出了什么问题,这是最讽刺的事。我现在会额外在外面放一个探活,定时请求监控面板或 Prometheus 的/health接口,一旦监控自身不可达,也会收到告警。另外,Prometheus 的存储不能无限增长,要有数据保留策略,比如只保留 15 天,并在磁盘容量上预留足够余量。
还有一个小技巧:监控是给人看的,不是为了攒数据。每次新加一个仪表盘图,先问自己“看到这张图我能做出什么决策”,如果答案是不确定,这个指标可以不放。不要让几百张图表淹没了真正有用的信息。
我平时最依赖的,其实就是uptime、vmstat、iostat、ss那几样基本功,以及一套能沉淀历史和自动告警的监控平台。系统监控不是一锤子买卖,它是在一次次故障复盘里慢慢养出来的。希望这篇内容能让你少走点弯路,下次再有人半夜打电话说“服务器卡了”,你至少知道从哪几个方向下手,而不是干瞪眼。