0. 前言:会写代码只是入门,会排障才是资深工程师
我们完成了Linux系统编程、网络编程、IO多路复用、Epoll实战、线程池、Redis/Nginx高并发架构的完整闭环。我们具备了开发百万并发服务的底层能力。
但线上生产环境和本地开发完全不同:线上会出现 CPU打满、内存暴涨、OOM宕机、磁盘IO卡死、连接泄漏、线程死锁、端口占用、网络丢包、服务雪崩等各类疑难故障。
很多开发者只会写业务代码,线上故障完全无从下手,只会重启服务,无法定位根因、无法复盘优化,这是初级和高级工程师的核心分水岭。
今天作为Linux底层系列收官实战章节,我们全覆盖线上99%高频故障场景,手把手掌握故障现象、排查命令、定位链路、根因分析、解决方案、复盘优化,形成标准化排障SOP:
1. CPU 100% 满载故障:死循环、频繁GC、线程切换、锁竞争排查
2. 内存泄漏/OOM宕机:内存持续上涨、句柄泄漏、堆栈分析
3. 磁盘IO打满:读写阻塞、日志爆盘、磁盘瓶颈定位
4. 网络连接异常:连接泄漏、TIME_WAIT暴涨、ESTABLISHED堆积
5. 线程死锁、阻塞卡死、服务假死故障精准定位
6. 高并发服务卡顿、吞吐量暴跌、延迟飙升根因复盘
7. 一套可落地的线上故障标准化排查流程(企业通用SOP)
1. 线上排障核心思维:先现象、再监控、后根因
所有线上故障,严禁盲目重启服务!标准排查顺序:
1. 看整体负载:top、uptime 确认整机资源瓶颈;
2. 定位故障维度:CPU/内存/磁盘/网络/线程 五大维度锁定问题;
3. 精准定位进程/线程:锁定异常PID、TID;
4. 抓取现场快照:日志、堆栈、连接状态、系统参数;
5. 临时恢复服务:止损优先,再复盘根因;
6. 优化兜底:代码修复、配置调优、监控告警、限流防护。
2. 故障一:CPU 100% 满载故障(最高频)
线上最常见故障,服务CPU持续跑满,导致接口超时、吞吐量暴跌、服务雪崩。
2.1 常见根因
1. 代码死循环、空循环、无sleep轮询;
2. 线程频繁上下文切换、大量线程竞争;
3. 锁竞争激烈、自旋锁空转;
4. Java/Golang频繁GC、内存抖动;
5. 大量短时连接、频繁创建销毁线程/进程。
2.2 标准化排查步骤
步骤1:全局查看CPU负载
# 查看整机负载、CPU使用率 top # 查看1分钟、5分钟、15分钟平均负载 uptime重点观察:us用户态、sy内核态、id空闲率,判断是代码问题还是内核问题。
步骤2:锁定CPU最高的异常进程
# 按CPU排序展示进程 top -o cpu # 精准查看进程CPU占用 ps -aux --sort=-pcpu | head -10步骤3:定位进程内CPU最高的线程
# 展示进程内所有线程,按CPU排序 top -H -p 进程PID # 查看线程详细堆栈、CPU占用 ps -mp 进程PID -o THREAD,tid,time步骤4:抓取线程堆栈,定位代码死循环位置
# Linux原生抓取进程堆栈 pstack 进程PID # 高性能排查,抓取线程运行状态 strace -p 进程PID2.3 故障判定与解决方案
现象1:用户态CPU高:业务代码死循环、空轮询、逻辑异常,定位堆栈代码行修复;
现象2:内核态CPU高:频繁系统调用、线程切换、网络读写频繁、锁竞争,优化IO模型、减少线程数量、优化锁机制;
现象3:软中断CPU高:网络流量过大、网卡中断频繁,调整网卡队列、开启多队列网卡。
3. 故障二:内存泄漏 & OOM宕机故障
服务运行越久内存占用越高,不重启不释放,最终被系统OOM杀死,是高并发服务顽疾。
3.1 常见根因
1. 代码内存未释放、全局内存堆积;
2. 文件句柄、Socket连接句柄泄漏;
3. 用户态缓存无淘汰、内存池只申请不回收;
4. 进程僵尸内存、内核内存泄漏;
5. 日志缓冲区、读写缓冲区无限堆积。
3.2 标准化排查步骤
步骤1:查看整机与进程内存占用
free -h top -o rss步骤2:排查文件句柄泄漏(90%内存泄漏都是句柄泄漏)
# 查看进程打开的所有文件句柄 lsof -p 进程PID # 统计句柄数量,判断是否超限 lsof -p 进程PID | wc -l # 查看系统句柄上限 ulimit -n步骤3:排查Socket连接泄漏
# 统计所有网络连接状态 ss -s # 查看进程所有网络连接 netstat -anp | grep 进程PID步骤4:查看OOM宕机日志,定位被杀进程
dmesg | grep -i oom3.3 解决方案与优化
1. 修复代码资源未释放问题:fd、socket、内存、缓存主动回收;
2. 增加内存、句柄监控告警,提前发现上涨趋势;
3. 增加缓存淘汰策略、内存池复用机制;
4. 调整系统句柄上限、进程最大内存限制。
4. 故障三:磁盘IO打满、服务卡顿阻塞
磁盘IO 100%,导致日志写入、文件读写、数据持久化阻塞,业务请求大面积超时。
4.1 常见根因
1. 日志疯狂打印、日志不切割、日志爆盘;
2. 频繁磁盘读写、同步刷盘;
3. 磁盘坏道、磁盘性能瓶颈;
4. 大量小文件读写、频繁fsync。
4.2 标准化排查步骤
步骤1:查看磁盘IO负载
iostat -x 1 # 查看实时磁盘读写进程 iotop -o步骤2:定位大文件、日志堆积
# 查看磁盘占用 df -h # 查找大文件 find / -size +100M # 查看目录占用 du -sh /*步骤3:排查进程磁盘读写行为
strace -p 进程PID -e trace=file4.3 解决方案
1. 配置日志切割、日志归档、过期日志自动删除;
2. 业务日志分级打印,关闭冗余DEBUG日志;
3. 优化刷盘策略,批量异步刷盘,减少频繁fsync;
4. 更换高性能SSD磁盘,隔离日志盘与数据盘。
5. 故障四:网络连接异常、连接泄漏、端口堆积
高并发服务最隐蔽故障:连接不释放、TIME_WAIT暴涨、ESTABLISHED堆积、端口耗尽、新连接无法建立。
5.1 四大连接异常场景
1.TIME_WAIT 过多:短连接频繁创建销毁,端口耗尽,无法新建连接;
2.ESTABLISHED 堆积:连接泄漏、客户端不断开、服务不释放连接;
3.CLOSE_WAIT 大量存在:客户端关闭连接,服务端未调用close,句柄泄漏;
4.端口占用冲突:服务重启失败、端口被残留进程占用。
5.2 排查与解决命令
# 统计各状态连接数量 netstat -an | awk '{print $6}' | sort | uniq -c # 查看TIME_WAIT连接 ss -s # 查找端口占用进程 lsof -i:端口号 # 强制释放端口、杀死残留进程 kill -9 进程PID5.3 内核参数优化(生产标配)
针对高并发短连接,优化内核TIME_WAIT回收机制:
# 快速回收TIME_WAIT连接 net.ipv4.tcp_tw_reuse = 1 # 开启端口复用 net.ipv4.tcp_tw_recycle = 1 # 调整最大文件句柄、最大连接数 net.core.somaxconn = 655356. 故障五:线程死锁、服务假死、请求卡死
服务进程存活、端口监听正常,但所有请求卡死、不响应、吞吐量为0,典型线程死锁/线程阻塞故障。
6.1 死锁四大必要条件
互斥持有、请求保持、不可剥夺、循环等待,四个条件同时满足即触发死锁。
6.2 精准排查步骤
# 查看进程所有线程状态、堆栈 pstack 进程PID # 查看线程阻塞、锁等待状态 ps -T -p 进程PID # 跟踪系统调用阻塞点 strace -p 进程PID通过堆栈信息可精准定位:哪两个线程互相持有锁、阻塞在哪一行代码。
6.3 解决方案
1. 统一锁的获取顺序,杜绝循环等待;
2. 增加锁超时机制,避免永久阻塞;
3. 减少大锁、粗粒度锁,细化锁范围;
4. 增加线程监控、死锁告警机制。
7. 高并发服务专项故障:吞吐暴跌、延迟飙升
资源无打满、无报错、无宕机,但服务越来越慢、QPS持续下跌、接口延迟翻倍,属于高并发隐蔽故障。
7.1 核心根因
1. Epoll事件堆积、粘包处理异常、数据残留阻塞事件循环;
2. 线程池任务队列堆积、线程阻塞、任务积压;
3. 网络重传、丢包、网络抖动;
4. 慢请求、大Key、慢SQL阻塞整体流程;
5. 内核参数不合理、TCP拥塞控制异常。
7.2 排查方案
1. 查看网络丢包、重传:netstat -s;
2. 监控线程池队列堆积、线程活跃数;
3. 抓取慢请求、大流量请求日志;
4. 校验TCP连接状态、内核超时参数。
8. 企业级线上故障通用SOP(可直接落地)
1. 紧急止损:降级、限流、熔断、切流量、重启备用节点(优先保可用)
2. 现场快照留存:进程堆栈、网络状态、系统日志、磁盘文件、监控曲线
3. 资源维度定位:CPU/内存/磁盘/网络/线程 五大维度锁定瓶颈
4. 代码与架构定位:锁、IO、循环、连接、缓存、线程池逐一排查
5. 根因修复:代码修复、配置调优、内核优化、架构升级
6. 防护兜底:新增监控、告警、限流、超时、重试机制,杜绝复现
9. 本章高频面试&复盘问答
Q1:线上CPU100%如何快速定位根因?
先用top定位高CPU进程,再通过top -H定位进程内高负载线程,配合pstack抓取线程堆栈,区分用户态死循环逻辑、内核态线程切换/锁竞争问题,针对性修复代码或优化系统参数。
Q2:CLOSE_WAIT大量堆积的原因与解决?
客户端主动关闭连接,服务端未读取剩余数据、未执行close释放fd,导致连接僵死、句柄泄漏。解决:优化读写逻辑,检测连接断开状态,及时关闭fd、回收资源,增加连接超时销毁机制。
Q3:内存泄漏和OOM的区别?
内存泄漏是内存缓慢持续上涨、长期不释放,属于慢性故障;OOM是系统内存耗尽,直接杀死进程,属于急性宕机故障。内存泄漏长期不处理,最终一定会触发OOM宕机。
Q4:服务假死、进程存活但不响应如何排查?
大概率是线程死锁、主线程阻塞、事件循环卡死、线程池全部工作线程阻塞。通过pstack查看线程堆栈,定位锁等待、IO阻塞、任务堆积位置,修复阻塞逻辑、增加超时与容错机制。
10. 1-151天全系列终极收官总结
我们从零完整闭环后端底层核心技术体系:
✅ 系统基础:进程、线程、信号、IPC、用户态内核态、文件IO
✅ 网络核心:Socket、TCP/UDP、粘包拆包、协议底层、连接机制
✅ 并发模型:BIO/NIO/Select/Poll/Epoll、线程池、异步解耦
✅ 工业架构:Redis单线程事件驱动、Nginx多进程百万并发架构
✅ 线上实战:全场景故障排查、性能调优、应急止损、复盘优化
我们完成体系学习,彻底摆脱只会写业务代码的困境,具备底层源码理解、架构设计、性能调优、线上排障、问题复盘的资深工程师核心能力。