简介
我们使用的是ECS部署的应用,因为是云产品,可以配置很多的告警指标,其中有一个关键指标就是磁盘使用率,对成熟的公司来说日志数据和业务数据同等重要‼️,甚至可能会更重要一些。log数据能够帮助我们定位问题和做一些修复性的工作。
问题:ECS磁盘告警
我们ECS采用的是ssd云盘,大小为40G,正常来说系统+应用相关文件磁盘使用不会超过50%,因为我们日志会根据日期和文件大小进行分割,有效期7天(非核心业务逻辑,保存有效期可以降低)。因为一次优化日志导致logback配置错误,导致生产日志没有分割😭,导致log文件过大,磁盘使用率升高。同时因为调试linux 定时任务(crontab)导致业务日志被输出多次,每次重启都会将业务日志同步输出到一个新的log文件中,导致经常触发磁盘使用率超过警戒线告警。
处理方案:
step1:登录相关ECS到log目录下使用命令: du -h 查看日志文件大小
step2:使用命令:true > xxx.log 对日志文件进行覆盖
step3: 使用命令:jps 查看正在运行的java程序
step4:使用命令:kill -15 xxx 任务结束后结束进程xxx
为什么要kill 掉任务进程,不是已经覆盖掉了吗?
因为当前真实大小是已经覆盖清空了文件内容,但是如果不重启,是不会被释放掉,因此需要重启应用,而且如果不从重启直接覆盖我们日志采集结果也会不准确。因此此处需要重启。
step5:找到调试crontab产生的日志问文件夹
step6:使用命令:sudo rm -rf 调试产生的log文件名.log (此步骤为危险步骤,慎用!!!)
至此,已经释放了ECS磁盘使用空间(调试crontab所产生的log文件并没有被释放,因此还占用着大量空间)
问题2: 清理后很快就会重新触发磁盘使用率告警
按照上述的方案,我们到系统根目录使用使用命令:du -h 查看磁盘使用也就7GB,远远没有达到80%?为什么会告警呢?于是找到运维同学请教了这个问题。
原因:
在Linux或Unix系统中,通过使用rm删除文件的原理,rm命令只是从文件系统的目录结构上解除链接(unlink),也就是说如果文件是被打开的(有一个进程正在使用该文件句柄),那该进程还是可以读取已删除的文件,而我删除的正是在运行中的MySQL的Logs,删除的时候文件正在被使用中,所以并不释放磁盘空间
怎么确定是由此原因导致没有释放磁盘空间呢?
可以采用lsof查看已经删除的文件中,查看哪些比较大的文件还在被调用
多数系统lsof未安装,需自己yum install lsof -y 安装
查看删除未释放的文件:
lsof |grep -i delete
可以查看到一文件标识“deleted”但依然被less进程锁定
删除关联进程(因为删除的同类文件比较多因此采用循环杀掉进程)
#如果只是删除某个文件可以根据pid(参考上图)
命令:ps -ef|grep 1424
#只要杀掉关联的进程就可以释放空间了
# 循环杀掉进程释放文件
lsof |grep -i delete|grep /app/project/devops-xxl-job/startup.sh|awk '{print $2}'|xargs kill
总结
删除文件时要确认文件删除对业务无影响,无价值才可进行删除。kill 进程时尽量使用kill -15 PID 正常退出进程,退出前可以被阻塞或回调处理。尽量不要使用kill -9 PID kill -9 PID 内核级别强制杀死一个进程。