问题发现

Zabbix Server 内存使用率从正常的 40% 持续攀升,最终超过 95%,Web 界面响应变慢,监控数据出现延迟。

监控系统自己出了问题——这是运维最尴尬的场景。


排查过程

第一步:确认是内存泄漏还是正常增长

# 查看内存详细分布
pmap -x $(pgrep zabbix_server) | tail -5

发现匿名内存映射异常偏高,指向内存泄漏。

第二步:分析日志

grep "history syncer" /var/log/zabbix/zabbix_server.log | tail -50

发现 history syncer 进程持续报警,处理队列不断增长——数据生成速度超过了处理速度。

第三步:定位泄漏位置

使用 Valgrind 进行内存分析,定位到 history 处理代码中的具体泄漏点:循环内的内存分配没有对应的释放操作。


修复方案

方案一(简单): 在循环结束时显式释放内存

// 修复前:循环内分配,无释放
for (i = 0; i < count; i++) {
    char *buf = malloc(size);
    process(buf);
    // 缺少 free(buf)
}

// 修复后
for (i = 0; i < count; i++) {
    char *buf = malloc(size);
    process(buf);
    free(buf);  // 添加释放
}

方案二(性能更好): 预分配内存,循环内复用

char *buf = malloc(size);
for (i = 0; i < count; i++) {
    process(buf);  // 复用同一块内存
}
free(buf);

预防措施

监控 Zabbix 自身:

# 在 Zabbix 中添加对自身的监控
监控项:proc.mem[zabbix_server,,avg]
告警阈值:持续1小时增长超过 100MB
目标值:内存使用率 < 70%

定期维护:

  • 每周检查日志,关注队列积压趋势
  • 每月进行压力测试
  • 评估缓存参数配置是否合理

核心教训

预防胜于修复。严格的内存管理规范、代码审查中关注资源对称性(分配必须有释放)、自动化内存泄漏检测——这三点能避免大多数类似问题。