跳到正文

内存泄漏

SysAdmin Crisis 中的内存泄漏:某台机器上的某个进程一直不归还内存。了解它的日志特征以及如何与其他事件区分。

最后更新:

泄漏是事件目录中最安静的一个。没有尖峰,没有溢出——只是某台机器上的某一个进程不再归还内存。

它做什么

一台机器的 RAM 在数分钟内而不是数秒内爬升。到达上限时,OOM killer 开始带走进程,而这本身就是一次服务中断。无物可带时,机器进入 DOWN。

要紧的细节是,这是局部的。它只影响一台机器,也只影响 RAM——不是带宽,不是磁盘,也不是整个服务器群。

日志特征

内存百分比先在 monit 中攀升;到达上限时,内核引入 OOM killer。OOM 记录说明的是谁调用了 killer,而不是泄漏进程的 PID:

02:41:08 web-02 monit[601]: 'web-02' mem usage of 80% matches resource limit [mem usage > 75.0%]
02:43:52 web-02 monit[601]: 'api-worker' mem usage of 38% matches resource limit [mem usage > 25.0%]
02:45:10 web-02 kernel: nginx invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=0

free 显示整体情况,top 显示哪个进程在增长。把进程列表按内存用量排序;泄漏的进程未必就是 OOM 记录中点名的那个。

置之不理的后果

OOM killer 按顺序逐个处理进程列表,所以在丢掉机器之前,功能会一块一块地丢失。由于机器会先进入 CRIT 再进入 DOWN,可用率的损失不是以单独扣分的形式出现,而是通过服务器状态体现——宽限期过后,再加上 SLA 债务。

如何区分

看起来相似区分依据
DDoS 洪水洪水会推高所有 Web 机器的 CPU 和带宽;泄漏只推高其中一台的 RAM。
磁盘写满两者都没有尖峰,都是缓慢爬升;但一个是 RAM,另一个是挂载点。df 一行就能判明。
失控任务两者都会在 top 输出中点出一个进程。失控任务占满 CPU;泄漏则让内存增长。

何时出现

最早出现的夜2
前提一台 web 机器
权重100——与游戏中最可能出现的事件并列
同时出现一个实例