国庆回来发现我在公司负责写控制录像程序定时或定空间大小截断的Java程序,但是服务器突然奔溃了,导致我的磁盘中.config文件一片空白,查docker日志呗
java.io.IOException: No space left on device
at java.base/java.io.FileOutputStream.writeBytes(Native Method)
2023-09-22 16:34:05.498 INFO 1 --- [ scheduling-1] com.wg.controller.VideoController : 正在进入跨天逻辑:2023-09-22/Record420/3D/16-04-03_3DM_LR.mp4
2023-09-22 16:34:05.498 INFO 1 --- [ scheduling-1] com.wg.util.FileUtil : allocatedRecordSize=10000
at java.base/java.io.FileOutputStream.write(FileOutputStream.java:341)
at com.wg.util.FileUtil.inputStreamToFile(FileUtil.java:41)
at com.wg.util.FileUtil.reNewMsgToConfigFile(FileUtil.java:131)
at com.wg.controller.VideoController.endDir(VideoController.java:105)
at com.wg.job.Time.reportCurrentUnRunningProcess(Time.java:61)
at jdk.internal.reflect.GeneratedMethodAccessor72.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
2023-09-22 16:34:05.498 INFO 1 --- [ scheduling-1] com.wg.util.FileUtil : allocatedRecordTime=1800
2023-09-22 16:34:05.498 INFO 1 --- [ scheduling-1] com.wg.util.FileUtil : du -cm /home/op/Record/2023-09-22/Record420
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
1020 total
我一查发现是空间不足,所以写进去的都是空白了,源文件就丢了,由于只是开发环境也不需要考虑生产,连忙删了些空间,下面是我腾出去的空间
op@endoscope-ser-02:~/Record$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 751M 3.2M 747M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 231G 206G 14G 94% /
tmpfs 3.7G 280K 3.7G 1% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 2.0G 343M 1.5G 19% /boot
/dev/sda1 1.1G 6.1M 1.1G 1% /boot/efi
tmpfs 751M 24K 750M 1% /run/user/1000
上面能清晰的看到/空间已用百分之94,/dev/mapper/ubuntu–vg-ubuntu–lv 231G 206G 14G 94% /
在这个信息中,可以看到:
文件系统大小(Size)为 231GB
已用空间(Used)为 206GB
可用空间(Avail)为 14GB
使用率(Use%)为 94%
那么解决思路就清晰了,通过 df -h 命令输出并过滤出根文件系统的剩余磁盘空间百分比时,使用 grep 命令和 awk 命令来完成。以下是一条可以实现此目的的命令:
df -h | grep '/$' | awk '{print $5}' | tr -d '%'
这样输出的结果就是94
public static Boolean isValidAllocatedSize(String rawVideoPath, Config config) throws IOException {
//实时监控空间
Double usedSize = getFileContainsVideoSize(rawVideoPath);
log.info(rawVideoPath + "已用空间usedSize:" + usedSize + "MB");
Double allocatedRecordSize = Double.parseDouble(config.getAllocatedRecordSize());
log.info("allocatedRecordSize:" + allocatedRecordSize + "MB");
//TODO 判断磁盘剩余空间率大小不得小于百分之6%
return checkSpaceUsePercentIsValid() && usedSize <= allocatedRecordSize;
}
/**
* 判断磁盘剩余空间率大小不得小于百分之6%
*
* @return java.lang.Boolean
* @author lst
* @date 2023/10/7 15:11
*/
public static Boolean checkSpaceUsePercentIsValid() {
String result = ExcuteLinux.exeCmd("df -h | grep '/$' | awk '{print $5}'");
int spaceLeftPercent = 100 - Integer.parseInt(result.trim());
return spaceLeftPercent >= 6;
}
上面的程序是我原先判断已用空间和剩余空间的关系,现在再加上判断磁盘剩余空间率大小不能小于百分之6的约束,基本就能保证上面的问题不会复现了。