
1. 引言为什么我们需要时刻关注系统资源作为一名长期与Linux服务器打交道的运维工程师或开发者我敢说查看CPU、内存和磁盘使用情况是每天打开终端后做得最多的事情之一。这不仅仅是例行公事更像是给系统做一次快速的“体检”。想象一下你管理的线上服务突然响应变慢用户投诉蜂拥而至这时候你的第一反应是什么没错就是连上服务器敲几个命令看看是CPU被哪个进程吃光了还是内存快爆了亦或是磁盘空间告急。这些命令就是你的听诊器和血压计能让你在几秒钟内定位到问题的症结所在。无论是排查线上故障、评估服务器性能瓶颈、规划硬件升级还是日常的服务器健康巡检熟练掌握这些资源查看命令都是必备的基本功。很多人觉得这些命令简单无非就是top、free、df但真正用起来里面的门道可不少。比如top里看到的CPU使用率100%就一定代表性能瓶颈吗free命令显示的“可用内存”为什么总是那么少df和du查出来的磁盘使用量对不上又是怎么回事今天我就结合自己多年的实战经验把这些命令里里外外讲透不仅告诉你怎么用更告诉你为什么这么用以及如何解读那些容易让人误解的输出信息。2. CPU使用情况深度剖析不只是看一个百分比CPU是系统的大脑它的繁忙程度直接决定了系统的处理能力。在Linux下我们有一系列工具来观察CPU的“工作状态”。2.1 实时监控之王top与htoptop命令是绝大多数人的首选。它提供了一个动态更新的全屏界面展示系统概览和进程列表。top刚进入top界面第一眼看到的汇总信息区Summary Area就包含了关键信息%Cpu(s): 这是CPU使用率的概览。它由多个部分组成us(user): 运行在用户空间非内核的进程所占用CPU时间的百分比。你的应用程序如Java、Python、Nginx都算在这里。sy(system): 运行在内核空间的进程所占用CPU时间的百分比。系统调用、中断处理、内核线程如ksoftirqd的消耗在这里体现。id(idle): CPU空闲时间的百分比。这个值高通常是好事。wa(iowait): CPU等待I/O通常是磁盘I/O完成的时间百分比。这是一个非常重要的指标。如果这个值持续很高比如超过5%-10%往往意味着磁盘是系统瓶颈CPU在“空转”等待数据。其他如hi硬中断、si软中断、st被虚拟化环境偷走的时间等在特定场景下也需要关注。注意很多人看到us或sy接近100%就紧张。这不一定代表有问题。如果系统正在执行一个计算密集型任务如科学计算、视频编码CPU利用率高是正常的。需要结合具体业务场景和响应时间来判断。真正需要警惕的是wa值过高或者us/sy高但系统整体吞吐量很低的情况。在进程列表区默认按CPU使用率降序排列。你可以看到每个进程的%CPU单个CPU核心的使用率百分比、TIME累计占用CPU时间等信息。htop是top的增强版界面更友好支持鼠标操作、颜色高亮、树状视图查看进程关系并且可以横向滚动查看完整的命令行。如果你的系统没有通常可以通过包管理器安装如yum install htop或apt install htop。htop使用htop时你可以按F6选择排序字段按F5以树状结构显示进程这对于理解父子进程关系非常有帮助。2.2 简洁快照mpstat与pidstat有时我们不需要持续的界面只需要一个时间点的快照或者想查看每个CPU核心的独立情况。mpstatMultiprocessor Statistics命令就派上用场了。它是sysstat工具包的一部分可能需要单独安装。# 查看所有CPU核心的统计信息每秒刷新一次共刷新5次 mpstat -P ALL 1 5这个命令的输出会清晰地列出每个逻辑CPU核心包括超线程出来的核心的%usr%sys%iowait%idle等。这对于排查多核CPU负载不均的问题非常有用。比如你可能发现只有一个核心的%sys特别高这可能是某个进程或内核线程被固定在了某个核心上。如果想查看具体是哪个进程在消耗CPUpidstat是另一个利器它也来自sysstat工具包。# 每2秒报告一次所有进程的CPU使用情况 pidstat -u 2 # 查看特定进程如PID为1234的详细CPU使用包括用户态和内核态 pidstat -u -p 1234 2 5pidstat的优势在于它可以分离出进程在用户态(%usr)和内核态(%system)的CPU消耗这对于分析程序性能瓶颈是业务逻辑复杂还是系统调用频繁非常有帮助。2.3 性能剖析的利器perf与火焰图当发现某个进程CPU使用率异常高时我们需要进一步深入知道是进程内部的哪些函数在消耗CPU。这时就需要用到性能剖析Profiling工具。perf是Linux内核自带的强大性能分析工具。一个常见的用法是使用perf top实时查看系统中消耗CPU最多的函数符号。sudo perf top更深入的做法是使用perf record采样并生成数据文件然后用perf report分析或者生成火焰图Flame Graph。火焰图能非常直观地展示出CPU时间在调用栈上的分布一眼就能找到“最宽”的那个函数即热点所在。生成火焰图通常需要几个步骤使用perf record采样使用perf script转换数据最后使用FlameGraph开源工具包中的脚本生成SVG图片。网上有大量关于“如何用火焰图分析CPU占用”的教程这正是解决“wechatappex.exe占用cpu高”或“lsass.exe cpu占用率高”这类问题的终极手段之一。通过火焰图你可以清晰地看到是哪个模块、哪个函数调用路径消耗了最多的CPU时间从而进行针对性优化。3. 内存使用情况详解理解“已用”和“可用”的真相Linux的内存管理非常复杂也导致了很多误解。直接看free命令的输出新手经常会吓一跳“我的内存怎么用了这么多可用内存只剩这么点了”3.1 解读free命令Buffers和Caches才是关键我们先看一个典型的free -h-h表示人类可读格式输出total used free shared buff/cache available Mem: 7.6G 1.2G 500M 200M 5.9G 6.0G Swap: 2.0G 0B 2.0Gtotal: 物理内存总量。used: 已使用的内存。注意这个值包含了buffers和cache所以它通常很大。free: 完全未被使用的内存。这个值小不一定代表内存紧张。shared: 主要用于tmpfs等共享内存。buff/cache: 这是理解Linux内存使用的核心。它是被内核用作**缓冲区Buffers和缓存Caches**的内存。Buffers: 主要用来缓存磁盘块的元数据如inode、dentry和临时存储即将写入磁盘的数据。Caches:Page Cache缓存从磁盘读取的文件内容。当你多次读取同一个文件时第二次及以后的速度会极快就是因为数据在内存的Page Cache里。available:这才是真正需要关注的“可用内存”指标。它估算的是在不进行Swap的情况下可以分配给新应用程序的内存大小。它包含了free内存和大部分可被回收的buff/cache内存。上例中虽然free只有500M但available高达6.0G说明内存非常充裕。核心原理Linux会利用所有空闲内存来做磁盘缓存Cache以提升系统性能。当应用程序需要更多内存时内核会自动、快速地将这部分缓存内存释放给应用程序。所以buff/cache占用的内存高是好事是内存被高效利用的表现而不是内存泄漏。3.2 深入进程内存/proc/pid/status与smemfree看的是全局我们还需要看具体每个进程的内存使用。top或htop里可以看到RES常驻内存和VIRT虚拟内存但还不够细。更详细的信息在/proc/[pid]/status文件里。例如查看PID为1234的进程cat /proc/1234/status | grep -E ‘VmRSS|VmSize|VmSwap’VmSize: 进程的虚拟内存大小类似VIRT。VmRSS: 进程实际使用的物理内存大小类似RES。这是该进程独占的、未被共享的内存。VmSwap: 进程被交换到Swap分区的内存大小。另一个好用的工具是smem它能展示进程的实际物理内存占用PSS和USS这对于评估共享库内存占用的应用如多个Apache进程非常有用。PSSProportional Set Size将共享内存按比例分摊到各进程比RSS更能反映真实内存压力。3.3 排查内存泄漏与OOM内存泄漏是服务器稳定性的一大杀手。持续观察free中的available趋势如果它在系统负载无明显变化时持续下降就可能存在内存泄漏。更直接的方法是使用vmstat命令观察内存和Swap的动态变化vmstat 1关注siswap in从磁盘交换到内存和soswap out从内存交换到磁盘两列。如果so长期大于0说明物理内存不足开始使用Swap了这会严重拖慢系统性能。当系统内存严重不足时内核的OOM KillerOut-Of-Memory Killer会被触发它会选择一个“最坏”的进程杀死以释放内存。可以通过dmesg | grep -i kill查看OOM Killer的历史记录。防止OOM的关键是合理设置应用程序的内存上限如JVM的-Xmx参数并确保/proc/sys/vm/overcommit_memory策略符合你的预期。对于像“antimalware service executable占内存”或“chrome内存泄露”这类问题思路是一样的先用top或任务管理器找到高内存进程再用更细的工具如smem 或在Windows下用Process Explorer分析其内存构成判断是工作集正常膨胀还是持续增长的内存泄漏。4. 磁盘使用与管理从空间到I/O的全方位监控磁盘问题通常分为两类空间不足和I/O性能瓶颈。我们需要不同的工具来应对。4.1 查看磁盘空间df与du的配合与差异查看磁盘空间使用率最常用的命令是dfdisk filesystem。df -h-h同样表示人类可读。这个命令显示的是文件系统层面的磁盘使用情况即每个挂载点如//home/var的总容量、已用量、可用量和使用百分比。当某个分区的使用率超过80%甚至90%时就需要警惕了这会影响系统运行和日志写入。那么是哪个目录或文件占用了大量空间呢这就需要dudisk usage命令来深入目录了。# 查看当前目录下各子目录的大小 du -sh * # 查找当前目录下最大的10个文件或目录 du -ah | sort -rh | head -n 10一个经典问题为什么df显示磁盘用了90%但用du -sh /统计根目录下所有文件的总和却远小于这个值这通常有以下原因已删除但未释放的文件如果有进程打开了一个大文件然后这个文件被删除了在进程关闭该文件句柄前磁盘空间不会被释放。可以用lsof | grep deleted命令查找这类文件。文件系统预留空间Ext文件系统默认会为root用户保留5%的空间可用tune2fs -l /dev/sda1 | grep ‘Reserved block count’查看这部分空间df会算入已用但du无法统计。磁盘快照或稀疏文件某些高级功能可能导致空间计算差异。4.2 监控磁盘I/O性能iostat与iotop磁盘空间够但系统还是很慢top显示%wa很高这很可能就是磁盘I/O瓶颈。iostat也来自sysstat包是分析磁盘I/O性能的标准工具。# 每2秒刷新一次显示扩展统计信息 iostat -dx 2关键列解读%util: 设备利用率。表示设备有I/O请求的时间百分比。如果持续接近100%说明设备I/O饱和是性能瓶颈。r/sw/s: 每秒的读/写请求数。rkB/swkB/s: 每秒读/写的数据量KB。await: 平均每次I/O请求的等待时间毫秒。这个值高说明磁盘响应慢。svctm: 平均每次I/O请求的服务时间毫秒。通常应小于await。如果iostat发现某个磁盘如sdb的%util和await很高下一步就是找出是哪个进程在疯狂读写它。这时要用到iotop可能需要安装。sudo iotopiotop类似于top但是用于显示实时磁盘I/O。你可以清楚地看到每个进程的读/写速率从而定位到“罪魁祸首”。对于解决“system占用磁盘100%”这类问题iostat配合iotop是黄金组合。4.3 磁盘挂载与文件系统管理在Linux中磁盘需要挂载到目录树才能使用。mount命令可以查看当前已挂载的文件系统。而磁盘挂载工具如经典的fdisk、parted或图形化的gparted用于对磁盘进行分区。在服务器上我们更常用fdisk或parted进行命令行操作。关于“linux磁盘挂载工具有哪些”除了上述分区工具挂载动作本身是通过mount命令完成的而让挂载在开机时自动生效则需要将配置写入/etc/fstab文件。这是一个需要谨慎操作的文件错误的配置可能导致系统无法启动。对于“搜狗磁盘管理”或“磁盘精灵”这类Windows下的工具在Linux中对应的可能是gnome-disks磁盘实用工具或GParted它们提供了图形化的分区、格式化、挂载和SMART检测功能对于桌面用户更加友好。5. 综合实战一个典型的高负载故障排查流程现在让我们把这些命令串起来模拟一个完整的故障排查场景一台线上Web服务器突然响应变慢请求大量超时。第一步快速全局概览首先使用top或htop快速查看。如果%Cpu(s)一行中wa值超过30%甚至50%初步怀疑磁盘I/O问题。如果us或sy值异常高则怀疑CPU计算瓶颈。同时观察Mem行看available内存是否充足Swap是否开始使用Si/So在vmstat中更直观。假设top显示%wa很高且available内存充足。第二步定位I/O瓶颈源打开另一个终端运行iostat -dx 2。观察是哪个磁盘设备比如/dev/sdb1的%util和await指标异常高。保持iostat运行再开一个终端运行sudo iotop。按o键只显示有I/O活动的进程。观察是哪个进程在对高负载的磁盘进行大量读写。假设发现是MySQL进程mysqld在大量写。第三步深入分析问题进程用pidstat -d -p mysql_pid 2查看该进程详细的I/O统计。同时可以用mysql客户端连接数据库执行SHOW PROCESSLIST;查看当前正在执行的慢查询或者检查慢查询日志。很可能是某个没有索引的大表全表扫描或者大量的磁盘临时表操作导致了疯狂的磁盘写。第四步检查磁盘空间虽然I/O高也顺带用df -h检查一下相关分区比如/var MySQL数据目录常在此的空间是否足够。磁盘满也会导致写操作异常。第五步制定解决方案根据分析结果采取行动如果是慢查询导致优化SQL语句添加索引。如果是日志写入过于频繁考虑调整日志级别或轮换策略。如果磁盘本身性能太差如机械硬盘考虑升级为SSD或者将数据库的日志文件如binlog、redo log放到更快的磁盘上。在整个过程中你可能还会穿插使用vmstat 1监控内存和Swap使用dmesg -T | tail查看内核有无报错信息。这套组合拳打下来绝大多数资源类性能问题都能被定位。6. 进阶工具与脚本化监控对于需要长期监控的场景我们不可能一直开着终端。这时就需要脚本化和使用更专业的监控系统。简单的Shell脚本可以写一个脚本定期收集top、free、df、iostat的输出保存到日志文件。#!/bin/bash LOG_FILE“/var/log/system_health_$(date %Y%m%d).log” echo “ $(date) ” $LOG_FILE echo “— Top CPU Processes —” $LOG_FILE top -b -n 1 | head -20 $LOG_FILE echo “— Memory Usage —” $LOG_FILE free -h $LOG_FILE echo “— Disk Usage —” $LOG_FILE df -h $LOG_FILE专业监控系统如Zabbix、Prometheus Grafana。它们可以持续采集服务器的CPU、内存、磁盘、网络等各项指标并绘制成美观的图表设置告警阈值。当CPU使用率超过80%持续5分钟或者磁盘空间低于10%时自动发送邮件或短信告警。这才是运维大规模集群的标配。例如Prometheus的node_exporter会暴露大量的系统指标Grafana则可以配置丰富的仪表盘来展示“CPU智能核心调度”情况、每个核心的负载、内存的详细组成active inactive slab等、磁盘的IOPS和吞吐量趋势图。这远比手动执行命令要高效和全面。7. 避坑指南与经验之谈最后分享一些容易踩坑的经验不要迷信free命令的free列真正该看的是available。看到free内存少就慌然后去盲目清理缓存echo 3 /proc/sys/vm/drop_caches可能会造成短时间内性能下降因为清理掉的缓存需要重新从磁盘加载。理解CPU负载Load Average与使用率的区别top第一行显示的load average: 1.05 0.70 0.65分别代表过去1、5、15分钟的系统平均负载。对于单核CPU1.0表示完全利用对于4核CPU4.0表示完全利用。它衡量的是处于可运行状态和不可中断状态的平均进程数。高负载可能由CPU繁忙、I/O等待进程因等待磁盘而阻塞等多种原因引起。所以高负载不一定等于高CPU使用率。df和du结果不一致时优先排查是否有进程占用了已删除的文件lsof | grep deleted。这是生产环境常见问题尤其是日志文件被rm删除但服务进程未重启时。警惕“软”RAID或LVM的性能问题在虚拟机或云主机中底层磁盘可能是网络存储或复杂的RAID。使用iostat时如果看到await异常高但%util不高可能意味着底层存储延迟高而非本地磁盘瓶颈。Swap的使用策略完全禁用Swap在某些情况下如内存充足且追求极致性能可行但保留少量Swap作为一个安全网是更通用的做法。当物理内存不足时内核可以先将不活跃的内存页换出避免直接触发OOM Killer导致关键进程被杀。可以通过/proc/sys/vm/swappiness来调整内核使用Swap的倾向性值越大越积极使用Swap默认通常是60。掌握这些命令和背后的原理就像是掌握了服务器的“语言”。当系统出现问题时你能听懂它的“诉说”快速找到病因而不是盲目地重启了事。这种能力正是在处理“k8s虚拟机cpu占用率太高”、“linux服务器cpu不足排查”等复杂问题时区分新手和老手的关键所在。