系统故障测试学习思路

张开发
2026/4/13 5:35:25 15 分钟阅读

分享文章

系统故障测试学习思路
系统故障测试学习思路本文用“好记、易懂、能判断”的方式梳理常见系统故障OOM、栈溢出、段错误、死锁、CPU 100%、磁盘空间不足、文件句柄耗尽、端口耗尽、内存泄漏、线程阻塞。重点不是只记名词而是学会看到现象后怎么判断到底是哪一种错误。一、先记住故障排查到底在看什么很多人一碰到系统故障第一反应是程序挂了响应慢了机器卡了日志爆错了但这些都只是“现象”不是“结论”。先记住一句总口诀先看现象再看资源再看日志最后定类型。排查时可以按这四步走看现象程序是崩了、卡了、慢了还是起不来看资源CPU、内存、磁盘、句柄、端口、线程哪个满了看日志有没有关键字比如 OutOfMemory、Segmentation fault、Deadlock、Too many open files定类型判断它到底属于哪一种典型故障一句话理解故障类型 现象 指标 日志 现场证据。二、先建立整体脑图2.1 常见故障可以分成四大类大类典型问题本质内存类OOM、栈溢出、内存泄漏内存不够用了或者一直涨不释放并发类死锁、线程阻塞多个执行单元互相等或者卡住不动资源类CPU 100%、磁盘满、文件句柄耗尽、端口耗尽系统关键资源被打满程序崩溃类段错误非法访问内存进程直接崩2.2 一张图记住排查路线程序异常 │ ├── 直接崩溃──────────────→ 看日志 / core / 系统事件 │ ├─ OOM Kill │ ├─ Segmentation fault │ └─ Stack overflow │ ├── 没崩但很慢────────────→ 看 CPU / 线程 / 锁等待 │ ├─ CPU 100% │ ├─ Deadlock │ └─ Thread blocking │ ├── 启动失败或功能异常────→ 看磁盘 / 句柄 / 端口 │ ├─ Disk full │ ├─ Too many open files │ └─ Address already in use / port exhausted │ └── 越跑越差──────────────→ 看内存曲线 ├─ Memory leak └─ 最终 OOM三、OOM内存溢出测试学习思路3.1 OOM 是什么OOMOut Of Memory就是程序还想申请内存但系统或进程已经给不出来了。通俗理解房间已经住满了还往里塞人。3.2 常见现象程序突然崩溃日志出现OutOfMemoryError、Cannot allocate memory容器/进程被系统直接杀掉服务响应越来越慢最后不可用3.3 怎么判断是不是 OOM重点看这几个证据证据 1日志关键字常见关键字OutOfMemoryJava heap spaceCannot allocate memoryKilledoom-killer证据 2内存监控持续打满表现进程 RSS 持续上涨可用内存持续下降Swap 被大量使用最终进程退出或被系统杀掉证据 3系统记录 OOM KillLinux 常见证据dmesg中出现 OOM killer 记录容器平台显示容器因内存超限被 kill3.4 怎么和“内存泄漏”区分OOM是结果内存泄漏常常是原因之一简单理解OOM 是“炸了”内存泄漏是“为什么越来越接近炸”。3.5 测试关注点大数据量处理时内存是否异常增长长时间运行后内存是否稳定并发增大时是否触发 OOM容器内存限制下是否容易被 kill四、栈溢出测试学习思路4.1 栈溢出是什么栈溢出Stack Overflow通常是函数调用太深调用栈撑爆了。最典型场景无限递归递归退出条件有问题单次调用里压栈数据过大4.2 常见现象程序执行到某一步突然崩日志出现StackOverflowError崩溃前堆栈反复出现同一个函数4.3 怎么判断是不是栈溢出证据 1日志关键字常见关键字StackOverflowErrorstack overflow证据 2调用栈非常深表现同一个函数反复递归调用调用链特别深错误点集中在递归函数证据 3内存并不一定整体打满这点很关键栈溢出不一定表现为整机内存耗尽而是线程栈空间不够。4.4 测试关注点递归算法的边界值异常输入是否导致无限递归深层嵌套数据处理是否会爆栈多线程场景下单线程栈大小是否合理五、段错误测试学习思路5.1 段错误是什么段错误Segmentation Fault通常表示程序访问了不该访问的内存。最常见于C/C 程序Native 扩展非法指针访问野指针、空指针、越界访问5.2 常见现象进程瞬间退出终端出现Segmentation fault系统生成 core 文件程序来不及打印完整业务日志5.3 怎么判断是不是段错误证据 1日志或终端关键字常见关键字Segmentation faultcore dumpedSIGSEGV证据 2进程是“直接崩”的表现不是慢慢卡死不是业务超时而是突然退出证据 3core 文件或崩溃栈如果能拿到 core dump基本就能进一步确认。5.4 怎么和 OOM 区分OOM常见是内存打满后失败或被杀段错误是非法访问内存往往瞬间崩记忆OOM 是“没内存可用”段错误是“乱碰内存”。5.5 测试关注点Native 库调用边界空指针、野指针、数组越界非法输入触发底层崩溃长时间运行后偶发崩溃六、死锁测试学习思路6.1 死锁是什么死锁就是你等我我等你大家都不干活。常见条件多个线程/事务相互持有资源同时等待对方释放6.2 常见现象程序不崩但卡住CPU 不一定高请求一直不返回线程数还在但吞吐接近 06.3 怎么判断是不是死锁证据 1线程都在等锁表现线程 dump 中多个线程互相等待日志出现 deadlock 相关信息数据库日志出现事务死锁证据 2程序“活着但不动”表现进程还在端口还在监听但请求卡住处理不往前走证据 3CPU 不一定高这点特别容易误判。死锁通常不是线程忙疯了而是线程都在傻等。6.4 怎么和“线程阻塞”区分死锁互相等彼此卡死线程阻塞可能只是等 I/O、等锁、等条件不一定形成闭环6.5 测试关注点多线程抢锁顺序是否一致多事务并发更新是否会互锁高并发下是否出现长时间无响应是否能自动超时回滚七、CPU 100% 测试学习思路7.1 CPU 100% 是什么就是CPU 被某个或某些线程打满了。通俗理解机器不是“卡住不干活”而是“忙到抬不起头”。7.2 常见现象响应明显变慢机器风扇狂转物理机系统负载高某进程 CPU 占用长期接近 100%7.3 怎么判断是不是 CPU 100%证据 1监控里 CPU 持续高表现总 CPU 高单个进程 CPU 高单个线程 CPU 高证据 2线程不是阻塞而是在持续运行常见原因死循环空转轮询大量计算GC 频繁自旋锁竞争证据 3请求慢但不是“完全卡死”通常表现为系统还能响应但明显很慢吞吐下降7.4 怎么和死锁区分CPU 100%线程忙个不停死锁线程等个不停记忆一个是忙死一个是等死。7.5 测试关注点死循环场景高并发计算场景GC 抖动场景自旋等待导致的 CPU 空耗八、磁盘空间不足测试学习思路8.1 磁盘空间不足是什么就是磁盘写满了程序再想写也写不进去。8.2 常见现象日志写不进去文件上传失败数据库报错服务启动失败程序提示No space left on device8.3 怎么判断是不是磁盘空间不足证据 1错误关键字常见关键字No space left on devicedisk full证据 2磁盘使用率 100%表现数据盘满日志盘满容器挂载盘满证据 3写相关操作普遍失败比如写日志失败创建临时文件失败下载失败数据落盘失败8.4 怎么和“文件句柄耗尽”区分两者都可能导致“文件打不开/写失败”但磁盘满空间没了句柄耗尽名额没了8.5 测试关注点日志暴涨场景大文件写入场景临时目录打满场景磁盘满后程序是否有明确报错九、文件句柄耗尽测试学习思路9.1 文件句柄耗尽是什么文件句柄可以理解成程序打开文件、socket、管道时占用的“号牌”。耗尽就是号牌发完了新的文件或连接再也拿不到。9.2 常见现象打开文件失败建立连接失败新请求进不来日志出现Too many open files9.3 怎么判断是不是文件句柄耗尽证据 1错误关键字常见关键字Too many open filesEMFILE证据 2进程打开文件数接近上限表现连接数很多文件数很多句柄数持续上涨不回落证据 3不是磁盘满但依然“打不开”这点是关键。磁盘还有空间但文件/连接就是打不开大概率看句柄。9.4 常见根因文件没关闭socket 没释放连接泄漏短连接太多句柄上限设置过低9.5 测试关注点高并发连接场景大量文件读写场景连接关闭是否及时长时间运行后句柄数是否持续增长十、端口耗尽测试学习思路10.1 端口耗尽是什么端口耗尽通常是客户端可用的本地端口快用完了新的连接建不起来。常见在大量短连接高频请求外部服务TIME_WAIT 太多10.2 常见现象新连接建立失败访问下游偶发报错高并发时请求突然大量失败错误信息带有地址、端口绑定失败10.3 怎么判断是不是端口耗尽证据 1连接建立失败但服务本身可能是好的也就是说对方服务正常网络也正常但本地发不出新连接证据 2大量 TIME_WAIT 或本地端口占满表现短连接很多本地临时端口被快速消耗证据 3错误关键字常见线索Address already in useCannot assign requested addressconnect 失败但目标服务正常10.4 怎么和“文件句柄耗尽”区分端口耗尽连接建立阶段就失败重点看 TIME_WAIT、本地端口范围文件句柄耗尽所有打开文件/socket 的动作都可能失败重点看 open files 上限10.5 测试关注点高频短连接压测Keep-Alive/连接池是否生效下游调用是否频繁建连断连TIME_WAIT 是否异常堆积十一、内存泄漏测试学习思路11.1 内存泄漏是什么内存泄漏就是申请了内存但用完后没有释放时间久了越积越多。11.2 常见现象程序刚启动没问题跑久了越来越慢内存曲线持续上涨最后可能演变成 OOM11.3 怎么判断是不是内存泄漏证据 1内存持续增长且不回落关键不是瞬时高而是随着时间推移一路上升业务低峰也降不下来。证据 2重启后恢复运行后又慢慢涨这是很典型的信号。证据 3GC 后仍然回不去对托管语言尤其明显比如Full GC 后内存仍高堆对象持续增加11.4 怎么和 OOM 区分内存泄漏一个逐渐变坏的过程OOM最后爆掉的结果11.5 测试关注点长稳压测长时间运行大量对象创建销毁场景缓存是否无限增长连接、会话、上下文是否被错误持有十二、线程阻塞测试学习思路12.1 线程阻塞是什么线程阻塞就是线程没往前执行卡在等某个东西。它可能在等I/O锁条件变量网络响应下游服务12.2 常见现象请求很慢线程池满了CPU 不一定高程序看起来还活着但处理速度很低12.3 怎么判断是不是线程阻塞证据 1线程状态大量处于 WAITING / BLOCKED表现线程 dump 显示很多线程在等待线程池活跃线程数高但完成任务少证据 2CPU 不一定高因为线程可能没在算而是在等。证据 3卡点集中在 I/O、锁或远程调用例如等数据库等文件读写等网络返回等锁释放12.4 怎么和死锁区分线程阻塞线程被卡住但可能过一会儿恢复死锁形成闭环等待自己恢复不了12.5 测试关注点慢 SQL / 慢接口场景锁竞争场景下游超时场景线程池打满后的行为十三、怎么快速判断“到底是哪一种故障”这是最重要的一部分。很多问题表面很像但判断方法不一样。13.1 先看“程序是崩了还是卡了还是起不来”现象优先怀疑进程突然退出OOM、段错误、栈溢出进程还在但卡住死锁、线程阻塞进程还在但很慢CPU 100%、线程阻塞、内存泄漏写文件失败/启动失败磁盘满、文件句柄耗尽新连接建不起来端口耗尽、文件句柄耗尽13.2 再看“资源是谁满了”资源现象优先怀疑内存打满OOM、内存泄漏CPU 打满CPU 100%、死循环、频繁 GC磁盘打满磁盘空间不足句柄数打满文件句柄耗尽端口/TIME_WAIT 很多端口耗尽线程大量等待死锁、线程阻塞13.3 最后看“日志关键字”关键字常见故障OutOfMemory/Cannot allocate memoryOOMStackOverflowError栈溢出Segmentation fault/SIGSEGV段错误deadlock死锁Too many open files文件句柄耗尽No space left on device磁盘满Address already in use/Cannot assign requested address端口耗尽十四、测试时建议重点收集哪些证据以后做故障测试不要只记“挂了”。建议固定收这几类信息14.1 资源指标CPU 使用率内存使用率磁盘使用率文件句柄数端口连接数线程数、线程池状态14.2 日志证据应用日志系统日志容器日志崩溃日志 / core dump14.3 现场信息故障前做了什么操作是瞬间发生还是逐步恶化重启是否恢复是否可稳定复现一句话记忆排查不是猜是收证据。十五、学习顺序建议如果你是初学者推荐按这个顺序学第一阶段先学最常见的资源类问题CPU 100%OOM磁盘空间不足文件句柄耗尽端口耗尽第二阶段再学程序行为类问题线程阻塞死锁内存泄漏第三阶段再学崩溃类问题栈溢出段错误第四阶段做综合判断训练根据现象猜类型根据资源指标缩小范围根据日志关键字最终确认十六、最后记住这套口诀故障排查总口诀先看现象再看资源再看日志最后定类型。内存类内存一路涨最后炸是泄漏引发 OOM 的常见样子。并发类CPU 高是忙线程等是堵互相等不动就是死锁。资源类磁盘看空间句柄看名额端口看连接CPU 看谁跑满。崩溃类突然退出看崩溃OOM、爆栈、段错误。十七、建议你真正动手练的内容最后给最实用的建议不要只背定义要练“判断能力”。建议至少做这些练习故意制造高内存占用观察 OOM 前后的现象写一个递归程序观察栈溢出日志调用异常 Native 代码观察段错误表现做双线程抢锁实验观察死锁线程栈制造死循环观察 CPU 100% 现象写满测试目录观察磁盘满后的报错大量打开文件不关闭观察句柄耗尽高频创建短连接观察端口耗尽和 TIME_WAIT做长稳测试观察是否存在内存泄漏模拟慢 I/O 和慢下游观察线程阻塞现象当你能把“现象、资源、日志、根因”四件事串起来系统故障测试能力就真正建立起来了。

更多文章