开篇词 | 如何让 Linux 内核更好地服务应用程序?
一、写在前面
作为一名应用开发者或运维 / SRE 工程师,你大概率遇到过这样的场景:
- 线上服务突然TCP 重传率飙升,业务端到端延迟翻了好几倍,你盯着
ss -tin的输出,看到一堆retrans标记,但不知道为什么这个连接会重传; - 内存监控告警频繁,但
free -h显示可用内存还很多,swap 却在疯狂换入换出,业务性能剧烈抖动,你怀疑是 Page Cache 的问题,却无从下手; - CPU 的sys 利用率飙到 70% 以上,
perf top看到一堆内核态函数名,完全不知道哪个是元凶; - 服务莫名其妙 OOM,但业务代码里找不到内存泄漏,
/proc/meminfo里的 Slab 和 Shmem 藏着什么秘密?
这些问题,光靠业务视角是解决不了的。
你需要从系统、从内核的视角去重新审视它们。这并非要求你成为内核开发者,而是希望你能让内核知识为业务服务——当 TCP 重传发生时,普通操作者只看到"哪个连接在重传",而高手能看出"为什么会重传";当内存紧张时,普通人只看到"内存不够了",而高手能判断是"Page Cache 难以回收导致 load 飙高"还是"Page Cache 容易回收导致业务性能抖动"。
这正是本系列文章——《Linux 内核技术实战课》——想要帮你做到的事。
二、为什么应用 / 运维需要内核视角?
应用程序运行在内核之上,应用程序的每一个行为,最终都要通过内核与硬件打交道。
- 你写一个
malloc(),内核决定是否给你分配物理内存,以及什么时候把不活跃的页面换出; - 你发一个
send(),内核负责 TCP 拥塞控制、滑动窗口、重传定时器; - 你起一个线程,内核负责调度它到哪个 CPU 上执行,以及在上下文切换时保存/恢复寄存器状态;
- 你读一个文件,内核通过 Page Cache 缓存磁盘数据,减少 I/O 等待。
一条业务链路的稳定性,本质上是一系列内核子系统协同工作的结果。任何一个环节出问题——Page Cache 管理策略不当、内存分配路径上的 lock contention、TCP 拥塞控制算法与业务流量模型不匹配——都会直接表现为业务抖动、延迟上升、吞吐下降。
换句话说:不懂内核,你只能看到"症状";懂内核,你才能看到"病因"。也只有看到病因,你才能开出有效"药方"——比如是调整vm.dirty_ratio等 sysctl 参数,还是升级内核版本,又或者是修改业务的行为模式。
三、本课程要做什么:建立"基于数据的问题定位逻辑"
Linux 内核知识庞杂、学习曲线陡峭,这是事实。从进程调度、内存管理、文件系统、网络协议栈到设备驱动,每一块拿出来都可以写好几本书。
但我们的目标不是成为内核开发者,而是成为"能用内核知识解决生产环境实际问题"的工程师。
本课程的核心方法论是:以"解决问题、满足需求"的方式切入,围绕生产环境中最常见、最棘手的 4 类典型问题展开,每一类问题都按照“基础篇 → 案例篇 → 分析篇”三阶段递进:
- 基础篇:讲清楚应用程序是如何与该内核子系统"打交道"的——比如应用程序如何申请和释放内存、TCP 如何建连和断连、CPU 如何调度任务。这部分是"必备常识"。
- 案例篇:还原真实生产环境中的故障案例——Page Cache 管理不当导致 load 飙高 / 业务性能抖动;内存泄漏层层排查最终定位到 Shmem 或内核 Slab 缓存;TCP 拥塞控制导致吞吐剧烈波动;透明大页(THP)引发 sys CPU 飙升。
- 分析篇:提炼一套可复用的排查思路和工具链——遇到这类问题,第一步做什么、第二步做什么、每个步骤看什么数据、数据怎么解读。
我们希望通过这个过程,帮你建立一套"基于数据的问题定位逻辑":出了问题,不是靠猜、不是靠拍脑袋,而是靠实实在在的内核数据——/proc/meminfo、/proc/vmstat、ss -tin、perf top、tracepoint——来一步步定位根因。
四、四大模块一句话导航
本系列课程分为四大模块,外加一个加餐篇:
| 模块 | 一句话导航 |
|---|---|
| 模块一:Page Cache 管理 | 如何更好地利用 Page Cache 减少无谓 I/O,以及面对"难以回收致 load 飙高"和"容易回收致业务性能抖动"这两种典型问题如何分析解决。 |
| 模块二:内存泄漏 | 从应用程序内存分配/释放机制出发,通过 Shmem、Slab 等真实泄漏案例,带你在运行时一步步找到根因,而不必打断业务。 |
| 模块三:TCP 重传 | 厘清 TCP 建连/断连与收发包受哪些内核配置影响,分析拥塞控制导致的性能抖动,以及端到端时延变大的定位方法。 |
| 模块四:内核态 CPU 利用率飙高 | 深入 CPU 执行任务的机制,剖析透明大页(THP)的利弊双面性,探讨网络高吞吐场景下的网卡特性配置,给出 sys CPU 飙高的系统性分析思路。 |
| 加餐:tracepoint | 介绍如何利用 tracepoint 这把"手术刀"来精准分析内核 Bug,定位那些常规工具难以触及的深层问题。 |
五、给读者的学习建议
1. 动手做实验,别只看不练
内核知识是"做出来"的,不是"看出来"的。
本系列每一篇都会提供可复现的实验场景——可能是一个简单的 C 程序、一组 sysctl 参数调整、或者一个 stress 工具脚本。请一定在自己的测试环境里跑一遍,亲眼看看free -h的输出在内存压力下如何变化,亲身体验ss -tin在重传前后的数据差异。
只有亲手操作过,概念才会变成直觉。
2. 看数据,而不是凭感觉
“感觉内存不够了”、“感觉网络变慢了”——这些感觉没有意义。
有意义的是:/proc/meminfo里Active(anon)和Inactive(file)的比例是多少?/proc/net/netstat里的TCPRetransSegs每分钟增长多少?perf top里排在前面的内核符号是什么?
本系列反复强调的"基于数据的问题定位逻辑",核心就是用数据说话。请养成习惯:先采集数据,再分析数据,最后做出判断。不要跳步。
3. 不必一次搞懂所有细节
内核的每个子系统都可以深挖到天荒地老。我们的策略是“够用就好,按需深入”:先理解应用与内核的接口和交互方式,掌握常见的排查工具和分析思路,遇到具体问题时再针对性地深入那一块。
随着你处理的问题越来越多,你的内核知识体系会自然生长、不断丰满。
六、系列文章导航
本系列文章计划如下:
| 序号 | 标题 | 内容 |
|---|---|---|
| 01 | 开篇词:如何让 Linux 内核更好地服务应用程序? | 本文 |
| 02 | 模块一:Page Cache 基础——应用程序与磁盘 I/O 的缓冲层 | 基础篇 |
| 03 | 模块一:Page Cache 管理不当引发的生产故障案例 | 案例篇 |
| 04 | 模块一:如何分析 Page Cache 相关问题 | 分析篇 |
| 05 | 模块二:内存分配基础——从malloc()到缺页异常 | 基础篇 |
| 06 | 模块二:Shmem 内存泄漏、Slab 内存泄漏等真实案例 | 案例篇 |
| 07 | 模块二:一步步排查内存泄漏——从/proc/meminfo到 tracepoint | 分析篇 |
| 08 | 模块三:TCP 连接与传输的基础——哪些配置影响你的网络 | 基础篇 |
| 09 | 模块三:TCP 拥塞控制导致吞吐抖动与端到端时延案例分析 | 案例篇 |
| 10 | 模块三:如何高效分析 TCP 重传 | 分析篇 |
| 11 | 模块四:CPU 如何执行任务——从调度到 sys 利用率 | 基础篇 |
| 12 | 模块四:透明大页 THP 与网卡特性引发的性能问题 | 案例篇 |
| 13 | 模块四:系统性分析内核态 CPU 利用率飙高 | 分析篇 |
| 14 | 加餐:如何用 tracepoint 分析内核 Bug | 加餐篇 |
| 15 | 结束语:让内核知识真正为你所用 | 总结 |
下一篇预告:《模块一:Page Cache 基础——应用程序与磁盘 I/O 的缓冲层》
我们将从最基础的问题开始:当你read()一个文件时,数据到底经历了怎样的路径才到达应用程序?Page Cache 在其中扮演了什么角色?什么样的业务场景应该担心 Page Cache 带来的问题?敬请期待。
如果你在生产环境中遇到过与 Page Cache、内存泄漏、TCP 重传、sys CPU 飙高相关的棘手问题,欢迎在评论区留言分享你的经历。你的真实案例,可能就是下一篇文章的分析素材。
[exit=0]