发布时间:2026-09-18 12:32 更新时间:2026-09-18 12:32 阅读量:0
不少站长在排查磁盘告警时会发现,/var/log/journal 目录悄悄涨到了几个 GB,甚至把根分区顶满。这通常是 systemd-journald 的默认策略造成的:日志文件按一定大小滚动,但如果没有显式设置容量上限,它就会按可用磁盘空间的比例自行增长,长期运行的服务写日志又多,占用自然水涨船高。本文讲清 journal 的两种存储模式,给出清理与限额配置,并说明怎么按服务过滤日志。
journald 的日志存储分两种模式。volatile(易失)指日志只保存在内存里,路径是 /run/log/journal,重启即丢;persistent(持久)指日志落盘到 /var/log/journal,重启后仍能查询。很多发行版默认是「auto」:只有当 /var/log/journal 目录存在时,才会启用持久化,否则退回内存模式。
所以判断自己的服务器属于哪种,先看目录是否存在、以及 journald 当前认定的存储位置:
# 查看是否存在持久化目录
ls -ld /var/log/journal /run/log/journal 2>/dev/null
查看运行时认定的存储位置与容量上限
systemd-analyze cat-config systemd/journald.conf | grep -E 'Storage|SystemMaxUse'
直接看 journal 磁盘占用概况
journalctl --disk-usage
如果 --disk-usage 输出的数字远超预期,而 /var/log/journal 又确实存在,那就是持久化模式下缺少容量限制。想启用持久化,可以手动建目录并重启服务:mkdir -p /var/log/journal && systemctl restart systemd-journald;反过来,只想省空间、不需要历史日志,把 Storage 设为 volatile 也能立刻减轻磁盘压力,代价是重启后日志丢失,排障时就没有历史可查了。
磁盘已经告警时,先做清理再谈长期配置。journalctl --vacuum-size 会按总大小收缩归档日志,直到占用降到指定值以下;与之类似的还有 --vacuum-time(按时间保留)和 --vacuum-files(按归档文件数量保留)。清理针对的是已归档的 journal 文件,当前正在写的文件不会被删,所以不会影响服务运行。
# 把 journal 归档总量压到 500M 以内
journalctl --vacuum-size=500M
只保留最近 7 天的归档日志
journalctl --vacuum-time=7d
清理后确认实际占用
journalctl --disk-usage
需要提醒的是,vacuum 只是「事后收缩」,不会改变 journald 继续增长的默认行为。如果不配限额,过一段时间它还会重新涨回来。因此清理完要紧接着做持久化配置。
配置文件位于 /etc/systemd/journald.conf,改完执行 systemctl restart systemd-journald 生效。核心是下面这组参数:
[Journal]
Storage=persistent
Compress=yes
SystemMaxUse=500M
SystemKeepFree=1G
SystemMaxFileSize=50M
SystemMaxFiles=10
MaxRetentionSec=1month
逐项说明。SystemMaxUse 是持久化日志能占用的总上限,超过后 journald 会删旧归档,这是最直接的限制;SystemKeepFree 表示无论上限多少,都要给磁盘留出的空闲空间,两个条件同时约束,谁先触发就以谁为准;SystemMaxFileSize 控制单个日志文件滚动前的大小,配小一些便于按文件粒度保留;SystemMaxFiles 限制归档文件数量;MaxRetentionSec 按时间做兜底,超过一个月的老日志自动淘汰。Compress 开启后日志会压缩存储,对本就吃紧的磁盘有帮助。
还有两个容易忽略的点。其一,上面这组 System* 参数作用于持久化日志,如果当前是 volatile 模式,对应的是 RuntimeMaxUse 等 Runtime* 参数,别配错。其二,/etc/systemd/journald.conf 里默认大多被注释,直接追加或取消注释即可;某些发行版还会在 /etc/systemd/journald.conf.d/ 下放覆盖片段,用 systemd-analyze cat-config systemd/journald.conf 能看到最终合并结果,具体优先级以官方文档为准。
限额配好后,如果某个服务持续报错,日志仍会被快速刷满。这时要按单元过滤,找出噪音来源。journalctl 的 -u 指定 unit,-f 实时跟随,--since 限定时间范围,组合起来很适合排障:
# 只看 nginx 服务最近 1 小时的日志
journalctl -u nginx --since "1 hour ago"
实时跟随某服务输出,Ctrl+C 退出
journalctl -u php-fpm -f
按优先级过滤,只看 error 及以上
journalctl -p err -b
统计哪个服务产生的日志行数最多
journalctl --since today -o json | \
jq -r '.UNIT // "(kernel)"' | sort | uniq -c | sort -rn | head
最后一条依赖 jq,若没装可以先用 journalctl -u 服务名 | wc -l 逐个估算。找到刷屏的服务后,从应用侧修掉重复报错,比单纯压缩日志更有价值。另外,如果某个服务日志完全没必要进 journal,可以在 unit 里加 StandardOutput=null,但会丢失排障线索,建议谨慎使用。
小结一下:journal 涨到几个 GB 的根因,是持久化模式下缺少 SystemMaxUse 这类上限。处理顺序建议是先 journalctl --vacuum-size 救急腾空间,再在 journald.conf 里把 Storage、SystemMaxUse、SystemKeepFree、MaxRetentionSec 配齐并重启服务,最后用 journalctl -u 定位噪音服务从源头治理。不同发行版的默认值与配置文件位置略有差异,动手前先用 systemd-analyze cat-config 确认当前生效参数,以官方文档和实际环境为准。
| 📑 | 📅 |
|---|---|
| Docker容器时区不对?TZ变量与localtime挂载的正确用法 | 2026-09-17 |
| 服务器 swap 使用率飙升:正常换页还是内存真不够用 | 2026-09-17 |
| 系统盘满了却找不到大文件:被删除但仍被进程占用的句柄排查与恢复空间 | 2026-09-17 |
| MySQL表空间与ibdata1膨胀处理:独立表空间、碎片整理与磁盘回收 | 2026-09-17 |
| SSH 连接频繁断开与卡顿排查:心跳、MTU 与 DNS 反解 | 2026-09-17 |
| Linux网卡丢包与TCP重传排查:ip -s link、ss -ti与ethtool实战 | 2026-09-18 |
| Nginx 静态资源 404 与权限被拒排查:root、alias、try_files 的坑 | 2026-09-18 |
| systemd-journald 日志转发远程 syslog:rsyslog 对接与丢日志排查 | 2026-09-19 |
| MySQL连接被拒绝Connection refused逐层排查思路 | 2026-09-19 |
| Docker容器DNS解析异常排查:resolv.conf与自定义网络 | 2026-09-19 |