驯服rsyslogd内存狂飙:从日志洪灾到精准限流的实战配置

张开发
2026/6/6 10:38:53 15 分钟阅读
驯服rsyslogd内存狂飙:从日志洪灾到精准限流的实战配置
1. 当rsyslogd变成内存怪兽时发生了什么那天凌晨三点我的手机突然被报警短信轰炸——服务器内存使用率突破95%。连滚带爬爬起来SSH连上去top命令一看好家伙rsyslogd这个平时温顺的日志服务竟然吃掉了8G内存这场景就像小区里突然闯进一头哥斯拉把整个内存街区踩得稀烂。细看日志目录更吓人/var/log/messages已经膨胀到20GB打开一看全是容器疯狂输出的调试日志。这让我想起老家发洪水时的场景上游容器暴雨倾盆中游journald的蓄水池决堤下游rsyslogd的河道根本来不及泄洪最终淹没整个村庄服务器内存。典型症状其实很有规律内存使用曲线呈阶梯式增长最终卡死系统/var/log/journal/目录下有损坏的日志文件dmesg里能看到journal校验失败提示容器越多问题爆发越快后来我发现这其实是现代日志系统的三体问题systemd-journald负责采集rsyslogd负责转发容器应用疯狂生产日志。当三者平衡被打破就会引发链式反应。就像洪水暴发要同时治理上游水土流失、中游水库调度和下游河道疏通我们也需要一套组合拳。2. 诊断工具揪出日志系统的病灶2.1 第一现场勘查先用这组命令快速定位问题源# 查看内存占用排行榜 top -o %MEM # 检查rsyslog进程实际内存注意VSZ和RSS的区别 ps aux | grep rsyslog | grep -v grep # 查看journal日志完整性 journalctl --verify | grep corrupt最近一次事故中我发现有3个journal文件报Invalid object header错误。这就像水库出现了管涌必须立即处理。2.2 日志洪水溯源重点检查这些位置# 查看各日志文件大小 ls -lh /var/log/{messages,secure,maillog} # 实时监控日志写入速度每秒刷新 watch -n 1 du -sh /var/log/messages # 统计日志来源容器日志通常带k8s标签 journalctl -o json-pretty | grep k8s_pod | wc -l有次发现某台机器上单个Pod每秒产生2000条调试日志这相当于在市政排水管上接了消防栓3. 紧急抢险给rsyslogd戴上紧箍咒3.1 内存限制三板斧修改/etc/systemd/system/rsyslog.service.d/memlimit.conf没有就新建[Service] MemoryAccountingyes MemoryHigh8M # 软限制类似水位警戒线 MemoryMax80M # 硬限制相当于防洪堤高度这组参数效果就像给长江分段设置汛限水位当内存使用超过8M系统会温和限流达到80M直接触发OOM killer重启服务时记得systemctl daemon-reload systemctl restart rsyslog3.2 日志分级过滤在/etc/rsyslog.conf中添加# 限制journal转发速率单位秒 $imjournalRatelimitInterval 0 $imjournalRatelimitBurst 0 # 只记录错误级别日志 *.err;mail.none;authpriv.none;cron.none /var/log/messages这相当于在日志管道上加装过滤器原本的消防水带变成了滴灌系统。实测能将日志量减少90%以上。4. 治本之策重建日志生态系统4.1 journald存储优化编辑/etc/systemd/journald.conf[Journal] Storagepersistent # 改内存存储为磁盘存储 Compressno # 关闭压缩避免bug SystemMaxUse1G # 磁盘配额1GB这就像把临时蓄水池内存改建成永久水库磁盘。记得同步操作mkdir -p /var/log/journal systemctl restart systemd-journald4.2 容器日志分流对于Kubernetes环境在docker配置中增加{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }相当于给每个容器安装独立下水道避免都挤到主排水管。5. 长效防护机制5.1 监控预警配置Prometheus中添加这些监控项- name: rsyslog_memory rules: - alert: RsyslogMemoryHigh expr: process_resident_memory_bytes{jobrsyslog} 8 * 1024 * 1024 for: 5m labels: severity: warning5.2 定期维护脚本创建/etc/cron.weekly/log-maintenance#!/bin/bash # 清理30天前日志 find /var/log/journal -type f -mtime 30 -delete # 校验journal完整性 journalctl --verify记得给执行权限chmod x /etc/cron.weekly/log-maintenance经过这套组合拳治理后我们的服务器再没出现过日志洪水。现在rsyslogd的内存占用稳定在5-6MB就像驯服的野兽回到了笼子里。关键是要理解日志系统是个有机整体不能头痛医头脚痛医脚。就像治水需要全流域统筹日志治理也需要端到端的视角。

更多文章