一、 故事背景:来自运维的告警
近日运维同事找到我说你看看这台 113 的机器是不是你这边业务的,存储使用超出 80% 了,我心里一沉这确实是我的业务!根分区使用率超过 90% 就是高危状态,再涨一点系统就会无法创建日志、临时文件,甚至触发只读模式,导致业务服务崩溃。
我立刻远程登录服务器,心里嘀咕:“上周刚清理过日志,怎么又满了?” 带着疑问,一场服务器空间排查攻坚战正式打响。
二、 排查过程:抽丝剥茧找元凶
2.1 第一步:全局扫描——用 df -h 定位高危分区
登录服务器后,首先执行最常用的磁盘空间查询命令 df -h,快速掌握全局磁盘状态:
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 7.8G 0 7.8G 0% /dev
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 121M 7.7G 2% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
/dev/mapper/centos-root 92G 87G 5.3G 95% /
关键结论:根分区 / 总容量 92G,已用 87G,仅剩 5.3G,使用率高达 95%——这就是告警的根源!其他分区均正常。
2.2 第二步:逐层深挖——用 du -sh 定位大目录
根分区爆满,到底是哪个目录在“搞事情”?切换到业务目录 /data/work,执行 du -sh * | sort -rh 按大小排序查看子目录占用:
[root@localhost logs]# du -sh /data/work/* | sort -rh
41G /data/work/app-main
1.2G /data/work/service-gateway.out
131M /data/work/service-core.jar
107M /data/work/service-gateway.jar
107M /data/work/service-gateway-bak.jar
105M /data/work/service-business.jar
67M /data/work/service-core.out
34M /data/work/service-business.out
5.0M /data/work/logs
152K /data/work/service-data.jar
60K /data/work/cache
44K /data/work/service-gateway-mini.out
4.0K /data/work/service-data.out
4.0K /data/work/deploy.sh
关键结论:/data/work/app-main 目录独占 41G,是根分区爆满的头号嫌疑人!
2.3 第三步:精准定位——揪出 37G 超大日志文件
继续深入 app-main 目录,执行命令排查内部文件占用:
[root@localhost logs]# du -sh /data/work/app-main/* | sort -rh
37G /data/work/app-main/service-data.out
3.2G /data/work/app-main/data
243M /data/work/app-main/app-web.out
158M /data/work/app-main/app-web.jar
147M /data/work/app-main/app-web-test.jar
108M /data/work/app-main/service-data-bak.jar
94M /data/work/app-main/service-data-core.jar
8.3M /data/work/app-main/logs
3.1M /data/work/app-main/app-web-test.out
584K /data/work/app-main/log-system-default
168K /data/work/app-main/service-data-bak.out
4.0K /data/work/app-main/deploy.sh
0 /data/work/app-main/job-center
0 /data/work/app-main/file-upload
0 /data/work/app-main/log-data-default
真相大白!一个名为 service-data.out 的日志文件竟然占用了 37G 空间,其次是 3.2G 的 data 目录。
奇怪的是,Java 应用通常日志后缀为 .log,而此次爆满的是 .out 文件,说明这并非标准日志组件输出,而是应用启动时的标准输出/标准错误重定向文件,且未做任何限制策略,最终把根分区撑满。
三、 解决方案:分两步——紧急止损 + 长期根治
3.1 紧急处理:1分钟释放 37G+ 空间
核心目标是快速释放空间,避免系统崩溃,优先清理无风险的日志文件:
-
清空超大日志文件 直接清空文件内容(保留文件本身,避免应用因文件不存在报错):
# 清空核心超大日志 > rm -rf /data/work/app-main/service-data.out # 顺带清理其他较大日志 > rm -rf /data/work/app-main/app-web.out > rm -rf /data/work/app-main/service-data-bak.out执行后,根分区剩余空间瞬间从 5.3G 飙升至 42G+,告警解除!
-
按需清理 data 目录 先查看
data目录内容,判断是否为可清理的缓存/临时数据:# 查看 data 目录子项占用 du -sh /data/work/app-main/data/* | sort -rh # 查找 100M 以上的大文件 find /data/work/app-main/data -type f -size +100M | xargs ls -lh- 若为 缓存/临时文件:确认无业务依赖后直接删除
rm -rf /data/work/app-main/data/cache/* rm -rf /data/work/app-main/data/tmp/* - 若为 业务数据/数据库文件:严禁删除!后续需考虑扩容或数据迁移。
- 若为 缓存/临时文件:确认无业务依赖后直接删除
3.2 长期根治:排查 .out 大文件产生根源,从源头解决问题
清空日志只是“治标”,要想“治本”,必须从根源排查 .out 大文件的产生原因,而非单纯依赖日志轮转。排查思路如下:
- 检查应用启动脚本
- 查看
deploy.sh或启动脚本中是否存在java -jar xxx.jar > xxx.out 2>&1这类重定向命令,确认是否将标准输出/错误全部写入.out文件。 - 核实重定向策略是否合理,是否未做日志切割、大小限制。
- 查看
- 分析
.out文件内容构成- 执行
head -n 100 xxx.out和tail -n 100 xxx.out查看文件头部和尾部内容,判断输出的是正常业务日志、异常堆栈,还是调试信息。 - 若文件中大量是重复的调试日志或异常堆栈,需定位应用代码问题。
- 执行
- 核查应用日志配置
- 检查 Logback/Log4j 等日志框架配置文件,确认是否将日志正确输出到
.log文件,而非标准输出。 - 确认日志框架是否开启了日志级别控制、大小切割、过期删除等功能。
- 检查 Logback/Log4j 等日志框架配置文件,确认是否将日志正确输出到
- 规范应用启动与日志输出
- 若启动脚本存在不合理的重定向,调整为仅重定向启动异常到
.out,正常日志由日志框架管理。 - 对必须保留的
.out文件,限制其最大大小,超过阈值则自动截断。
- 若启动脚本存在不合理的重定向,调整为仅重定向启动异常到
3.3 额外优化建议
- 降低应用日志级别
若日志增长过快,大概率是应用日志级别设置为
DEBUG(输出大量冗余信息)。建议在应用配置文件中将日志级别改为INFO,减少日志输出量。 - 删除冗余 jar 包
排查发现存在重复 jar 包(如
service-gateway.jar出现两次),确认当前运行版本后,删除未使用的冗余包,释放空间。 - 配置磁盘使用率监控告警 通过 Zabbix、Nagios 等监控工具,配置根分区使用率告警阈值(建议 80%),提前预警,避免再次出现爆满情况。
四、 总结
Linux 服务器磁盘爆满问题,此次是典型的 Java 应用启动时标准输出重定向无限制 导致。解决这类问题的核心思路是:
- 紧急止损:用
df -h定位高危分区 → 用du -sh逐层排查大文件 → 安全清理日志/临时文件。 - 长期根治:排查启动脚本重定向策略 → 规范日志框架配置 → 从源头减少
.out文件的无效输出。
掌握这套排查和优化方法,就能轻松应对绝大多数 Linux 磁盘空间问题。