目录
[1. 文件删除的陷阱](#1. 文件删除的陷阱)
[2. 新建文件的误区](#2. 新建文件的误区)
[1. 监控告警设置](#1. 监控告警设置)
[2. forever启动参数优化](#2. forever启动参数优化)
[3. 使用PM2替代方案](#3. 使用PM2替代方案)
一次因磁盘空间清理导致的线上服务故障,让我重新认识了进程文件锁的重要性
事故回顾
今天早上,监控报警显示服务器磁盘占用率达到100%。登录宝塔面板后,我发现 /root/.forever/
目录下的日志文件体积巨大,于是直接删除了这些 .log
文件。本以为简单的「删除→新建同名文件」就能解决问题,结果服务直接崩溃,再也无法启动。
问题根源分析
1. 文件删除的陷阱
当我直接在宝塔面板上删除 .forever/*.log
文件时,实际上发生了以下情况:
bash
# 删除前
lsof | grep /root/.forever/74AI.log
# 输出:node 3284 root 1w REG 8,1 10485760 123456 /root/.forever/74AI.log
# 删除后(文件描述符仍然存在)
lsof | grep deleted
# 输出:node 3284 root 1w REG 8,1 10485760 123456 /root/.forever/74AI.log (deleted)
关键问题:虽然文件在文件系统中被标记为删除,但Node.js进程仍然持有该文件的打开句柄,磁盘空间并未真正释放!
2. 新建文件的误区
我尝试新建同名文件:
bash
touch /root/.forever/74AI.log
但这时候:
-
新建的文件inode与原来的不同
-
Node.js进程仍在向已删除的文件描述符写入日志
-
forever无法正确识别新的日志文件路径
正确的处理方案
方案一:优雅重启服务(推荐)
bash
# 1. 查看当前运行的服务
forever list
# 2. 正常停止服务
forever stop app.js
# 3. 清理日志文件(现在可以安全删除了)
rm -f /root/.forever/*.log
# 4. 重新启动服务
forever start app.js
方案二:如果服务已经崩溃
bash
# 1. 查找并杀死残留的Node进程
ps aux | grep node
kill -9 <pid>
# 2. 清理forever的元数据
forever cleanlogs
# 3. 或者彻底清理(谨慎使用)
rm -rf /root/.forever/*
forever restart app.js
方案三:处理磁盘空间的正确姿势
bash
# 1. 查看磁盘使用情况
df -h
# 2. 查找大文件
find / -type f -size +100M 2>/dev/null | head -20
# 3. 清空日志文件(而不是删除)
truncate -s 0 /root/.forever/74AI.log
# 4. 或者使用日志轮转
logrotate /etc/logrotate.d/forever
创建日志轮转配置
为了避免未来再次出现磁盘爆满的问题,建议设置日志轮转:
bash
# 创建日志轮转配置
cat > /etc/logrotate.d/forever << EOF
/root/.forever/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
}
EOF
预防措施
1. 监控告警设置
bash
# 添加磁盘监控脚本
#!/bin/bash
THRESHOLD=90
CURRENT=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
if [ "$CURRENT" -gt "$THRESHOLD" ] ; then
echo "磁盘使用率超过 ${THRESHOLD}%,当前:${CURRENT}%" | mail -s "磁盘告警" admin@example.com
fi
2. forever启动参数优化
bash
# 限制日志大小
forever start \
-l /var/log/myapp/forever.log \
--maxLogSize 10485760 \
--append \
app.js
3. 使用PM2替代方案
bash
# PM2提供更好的日志管理
npm install -g pm2
pm2 start app.js --name "tcpserver"
pm2 logs --lines 100 # 查看日志
pm2 flush # 清空日志
故障恢复检查清单
当遇到类似问题时,按照以下步骤排查:
-
✅ 检查磁盘空间:
df -h
-
✅ 检查进程状态:
forever list
或pm2 list
-
✅ 检查文件句柄:
lsof | grep deleted
-
✅ 检查系统日志:
dmesg | tail -20
-
✅ 逐步恢复服务
经验教训
这次事故让我深刻认识到:
-
不要直接删除正在被进程使用的日志文件
-
磁盘清理要有计划性,不能临时抱佛脚
-
生产环境操作前一定要有备份和回滚方案
-
完善的监控告警系统是运维的生命线
总结
通过这次痛苦的经历,我重新整理了服务器日志管理的最佳实践。现在我们的服务都配置了自动日志轮转和磁盘监控,再也不会因为日志文件导致磁盘爆满了。
记住:在Linux系统中,删除正在使用的文件并不会立即释放磁盘空间,正确的做法是清空文件内容或使用日志轮转工具。
运维无小事,每一个看似简单的操作背后都可能隐藏着陷阱。希望我的经验能帮助你避免类似的坑。