Linux 性能排查实战

📅 2026/8/26 18:35:37
Linux 性能排查实战
在日常运维中机器很卡是最常见也最模糊的问题描述。卡顿可能来自 CPU、内存、磁盘 IO、网络中的任何一个环节也可能是特定场景下的局部问题。本文从系统整体卡顿、打字延迟、内存泄漏三个层面给出一套可执行的排查方法论。目录一、系统卡顿排查框架1.1 一键快速定位1.2 分维度排查命令1.3 判断逻辑1.4 最常用的三板斧二、打字卡顿专项排查2.1 SSH 远程打字卡网络延迟或丢包SSH 服务端 DNS 反向解析MTU 不匹配2.2 本地终端打字卡终端模拟器资源消耗高桌面合成器卡顿输入法进程卡死Shell 配置过重终端大量输出滚动2.3 编辑器中打字卡2.4 快速定位法三、内存泄漏诊断3.1 什么是内存泄漏3.2 为什么要关注内存泄漏3.3 常见内存泄漏场景手动内存管理语言C/C缓存或集合只进不出资源句柄未关闭监听器和回调未注销长生命周期对象持有短生命周期引用第三方库缺陷运维侧的类泄漏3.4 排查方法四、总结一、系统卡顿排查框架系统卡顿的本质是资源瓶颈。Linux 系统的核心资源有四类CPU、内存、磁盘 IO、网络加上一个综合指标负载load average。排查时先定位是哪个维度的问题再深入分析。1.1 一键快速定位在排查初期用一条命令获取全局概览uptime echo --- top -bn1 | head -20 echo --- free -h echo --- vmstat 1 3这条命令依次输出系统负载、CPU 和进程概览、内存使用、虚拟内存统计。基本能在 10 秒内判断出卡顿方向。1.2 分维度排查命令维度命令关注指标整体负载uptimeload average 与 CPU 核数对比超过核数即为过载CPU 占用top按 P 排序%us 用户态、%sy 内核态、%wa IO 等待CPU 核明细mpstat -P ALL 1是否单核打满、是否有软中断%soft进程 CPUpidstat -u 1哪个进程持续消耗 CPU内存free -havailable 是否耗尽、swap 是否在用内存进程top按 M 排序哪个进程占内存最多换页vmstat 1si/so 持续非零说明在频繁 swap磁盘 IOiostat -xz 1%util 接近 100%、await 高说明磁盘瓶颈IO 进程iotop 或 pidstat -d 1哪个进程在大量读写网络流量iftop 或 nethogs是否被打满带宽、哪个进程占流量网络错误sar -n DEV 1rxerr/rxdrop 是否持续增长异常进程ps aux \awk $8 ~ /D\系统日志dmesg -T \tail -501.3 判断逻辑根据 top 输出中的 CPU 状态可以快速定位瓶颈类型• load 高 %us 高计算密集型进程用 top 找 CPU 占用最高的进程• load 高 %wa 高磁盘 IO 瓶颈用 iostat 和 iotop 定位• load 高 %sy/%soft 高内核或网络软中断开销大检查网络包量和内核参数• available 内存低 swap 活跃内存不足检查是否有内存泄漏或进程占用过高• %util 100% await 高磁盘性能不足或有坏道检查 dmesg 中的 IO 错误1.4 最常用的三板斧如果时间有限先执行这三条# 1. 谁在吃 CPU top -bn1 | head -15 # 2. 谁在吃内存 ps aux --sort-%mem | head -10 # 3. 是不是 IO 瓶颈 iostat -xz 1 3二、打字卡顿专项排查打字卡是一个比系统卡更具体的问题通常不是全局资源问题而是特定链路的延迟。需要区分场景来排查。2.1 SSH 远程打字卡这是最常见的场景表现为按键后字符延迟出现或者一串字突然一起蹦出来。常见原因和解决方法网络延迟或丢包用 ping 测试到服务器的网络质量如果延迟高或有丢包问题在网络层。弱网环境下可以用 mosh 替代 SSHmosh 基于 UDP 且支持本地回显体验远好于 SSH。ping -c 20 服务器IPSSH 服务端 DNS 反向解析SSH 默认会对连接 IP 做反向 DNS 解析如果 DNS 配置有问题每次操作都会卡顿。禁用即可sudo sed -i s/^#*UseDNS.*/UseDNS no/ /etc/ssh/sshd_config sudo sed -i s/^#*GSSAPIAuthentication.*/GSSAPIAuthentication no/ /etc/ssh/sshd_config sudo systemctl restart sshdMTU 不匹配如果大包卡顿但小包正常可能是 MTU 问题。用以下命令测试ping -M do -s 1472 网关IP不通则说明 MTU 需要调小或者在网关上配置 TCP MSS clamping。2.2 本地终端打字卡如果是在物理机或虚拟机的桌面环境中打字卡原因通常在终端模拟器或桌面环境层面。终端模拟器资源消耗高gnome-terminal、konsole 等终端在某些情况下会占用大量 CPU。可以换用 alacritty 或 kitty它们基于 GPU 加速响应极快。桌面合成器卡顿KDE 的 KWin 合成器、GNOME 的动画效果可能导致输入延迟。尝试关闭合成器或禁用桌面动画。输入法进程卡死ibus 或 fcitx 输入法进程异常会导致输入卡顿。重启输入法ibus restart # 或 fcitx5 -rShell 配置过重如果每次回车都卡一下可能是 shell 配置文件中有慢命令比如 git 状态查询、复杂的 prompt 渲染。用裸 shell 对比测试bash --norc --noprofile如果裸 shell 流畅就需要精简 .bashrc 或 .zshrc移除耗时插件或者使用异步 prompt 方案如 powerlevel10k。终端大量输出滚动如果有进程在疯狂打印日志终端渲染会成为瓶颈。用 CtrlS 暂停输出CtrlQ 恢复或者将输出重定向到文件。2.3 编辑器中打字卡只有在 vim 等编辑器中卡顿通常是编辑器本身的问题• 插件过多或语法高亮在大文件下性能差用 vim --noplugin 启动对比• 文件过大用 less 查看而非编辑或用 vim -u NONE 裸启动• 代码折叠导致卡顿执行 :set nofoldenable 关闭折叠• 交换文件写入慢检查磁盘 IO 是否正常2.4 快速定位法按以下顺序测试30 秒内可以定位问题层级# 1. 系统是否整体卡 uptime top -bn1 | head -5 # 2. 排除 shell 配置问题 bash --norc --noprofile # 3. 物理机切到 tty 测试CtrlAltF3排除图形环境影响 # 4. SSH 场景测试网络 ping -c 10 服务器IP判断逻辑• tty 里也卡系统负载或硬件问题• tty 流畅但图形终端卡终端模拟器、合成器或输入法问题• 本地流畅但 SSH 卡网络或 SSH 配置问题• 只有某个编辑器卡编辑器配置或大文件问题三、内存泄漏诊断内存泄漏是导致系统逐渐变慢、最终崩溃的常见原因。它的特点是渐进式的容易被忽视。3.1 什么是内存泄漏内存泄漏的本质是程序申请了内存但用完没有释放导致可用内存随时间持续减少。需要区分内存占用高和内存泄漏一个正常程序内存占用高但稳定是没问题的一个泄漏程序哪怕每次只漏 1MB长时间运行后也会耗尽所有内存。3.2 为什么要关注内存泄漏内存泄漏的危害是渐进的1. 初期几乎无感内存占用缓慢上升2. 中期可用内存不足开始频繁使用 swap系统明显变卡3. 后期 OOM Killer 随机杀掉进程服务崩溃4. 极端情况下系统卡死只能重启因此在排查系统卡顿和服务不稳定时内存使用趋势是必查项。3.3 常见内存泄漏场景手动内存管理语言C/Cmalloc/new 之后没有对应的 free/delete或者函数提前返回、抛出异常时跳过了释放逻辑。void bad_example() { char *p malloc(1024); if (error) return; // 直接返回p 没有释放 free(p); }缓存或集合只进不出这是所有语言中最常见的泄漏类型。HashMap、List、全局缓存无限追加数据但没有淘汰策略或清理机制。日志队列、任务队列的消费者跟不上生产者速度也属于此类。// 典型泄漏每个请求都 put但从不 remove static MapString, Object cache new HashMap(); cache.put(requestId, data);资源句柄未关闭文件描述符、数据库连接、Redis 连接、Socket 没有正确关闭这类泄漏最终会表现为 Too many open files 错误。线程创建后未退出也属于此类。监听器和回调未注销注册了事件监听器但对象销毁时没有反注册定时器没有 cancel。常见于 GUI 程序、Android 开发、前端组件销毁场景。长生命周期对象持有短生命周期引用Java 中静态集合持有 Activity 或 Request 对象导致整个对象图无法被 GC 回收。Python 中循环引用且定义了 __del__ 方法引用计数无法回收。闭包捕获了大对象且闭包被长期持有也会导致泄漏。第三方库缺陷驱动、JNI 库、native 扩展可能存在内存泄漏。某些版本的框架如 Netty、Tomcat 的特定版本也有已知的内存泄漏问题。运维侧的类泄漏日志文件只写不轮转导致磁盘占满、Docker 容器的 json-file 日志无限增长、/tmp 临时文件不清理。这些不是严格意义上的内存泄漏但现象和危害类似。3.4 排查方法判断是否存在内存泄漏核心是观察内存使用趋势# 观察特定进程的内存趋势每 2 秒采样 pidstat -r -p PID 2 # 或者用 watch 监控 RSS watch -n 5 ps -o pid,rss,vsz,comm -p PID # 系统整体内存趋势 free -h sar -r 1 10判断标准在没有新任务涌入的情况下进程的 RSS实际物理内存持续单调上升且不回落基本可以确定存在内存泄漏。正常程序在 GC 或空闲后内存会趋于平稳或下降。不同语言有更专业的排查工具• Javajmap 导出堆转储用 MAT 或 JVisualVM 分析• Gopprof 分析内存分配• C/Cvalgrind、AddressSanitizer• Pythontracemalloc、objgraph四、总结Linux 性能排查的核心思路是先全局后局部先资源后进程。系统卡顿用五维度模型快速定位打字卡顿按场景分层排查内存泄漏看趋势而非绝对值。掌握这套方法论后面对机器很卡这类模糊问题时就可以有条理地逐步缩小范围最终找到根因。排查工具只是手段理解各资源之间的关联和系统的运行机制才是关键。