磁盘空间不够引发的控制录像程序崩溃到后端的解决方式

国庆回来发现我在公司负责写控制录像程序定时或定空间大小截断的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的约束,基本就能保证上面的问题不会复现了。

你可能感兴趣的:(java)