问题发现
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%
定期维护:
- 每周检查日志,关注队列积压趋势
- 每月进行压力测试
- 评估缓存参数配置是否合理
核心教训
预防胜于修复。严格的内存管理规范、代码审查中关注资源对称性(分配必须有释放)、自动化内存泄漏检测——这三点能避免大多数类似问题。