SpringBoot引入主盘探活定时任务

主盘探活通常是指检查存储设备(例如硬盘)是否可读写,但在Java中并没有直接针对硬件级别的磁盘探活API。然而,我们可以模拟一个场景,即检查某个目录或文件是否可以被Java程序正常读写,以此作为主盘活跃的一个间接判断依据。

在这里插入图片描述

[Ref] What is @Scheduled does?

在这里插入图片描述

第1步:创建定时任务服务类
构造一个探活线程池,执行探活线程任务

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
@Component
public class StorageHealthyCheckTask {
    private static volatile AtomicBoolean isActive = new AtomicBoolean(true);

    @Value("${storage.path}")
    private String storagePath;
    @Value("${storage.needCheck}")
    private boolean needCheck;

    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(
            3, 3, 
            5, TimeUnit.SECONDS, 
            new LinkedBlockingQueue<>(1), 
            new ThreadFactoryBuilder().setNameFormat("探活检查-%d").setDaemon(true).build(), 
            new ThreadPoolExecutor.DiscardPolicy());

    @Scheduled(cron = "0/5 * * * * ?") // 每分钟执行一次
    private void storageHealthyCheck() {
        log.info("{}线程 调用:storageHealthyCheck start", Thread.currentThread().getName());
        if (!needCheck) {
            log.info("no need check");
            return;
        }

        // true表示正常状态,则已知探活
        if (BooleanUtils.isTrue(isActive.get())) {
            check(Paths.get(storagePath), isActive);
        } else {
            // false表示失败,则报错
            log.error("isActive:{}", false);
        }

        log.info("{}线程 调用:storageHealthyCheck end \n", Thread.currentThread().getName());
    }

    private void check(Path path, AtomicBoolean flag) {
        try {
            Future<Boolean> future = executor.submit(() -> {
                try {
                    log.info("{}线程 测试isReadable", Thread.currentThread().getName());

                    // true表示有读权限,false表没读权限,超时中断就会异常退出
                    return Files.isReadable(path);
                } finally {
                    // 只要路径存在且可读, 就可以认为存储服务是健康的
                    flag.set(true);
                }
            });

            Boolean res = future.get(2, TimeUnit.SECONDS);
            log.info("{}线程 isReadable结果: {}", Thread.currentThread().getName(), res);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 重新设置中断状态
            log.error("Thread was interrupted while waiting for the check task to complete.", e);
            flag.set(false);
        } catch (TimeoutException e) {
            log.error("Check task did not complete within the timeout of 2 seconds.", e);
            flag.set(false);
        } catch (CancellationException e) {
            log.error("Check task was cancelled before it could complete.", e);
            flag.set(false);
        } catch (ExecutionException e) {
            log.error("An error occurred while executing the check task", e);
            flag.set(false);
        }
    }
}

第2步:在application.yaml中添加定时任务相关的属性
配置支持探活开关,以主盘路径

storage:
  path: C:\Users\zhang\Desktop\test
  needCheck: true

第3步:添加@EnableScheduling注解来启用定时任务调度功能

@SpringBootApplication
@MapperScan("com.zhangziwa.practisesvr.mapper")
@EnableScheduling
public class PractisesvrApplication {

    public static void main(String[] args) {
        SpringApplication.run(PractisesvrApplication.class, args);
    }
}

第4步:单独记录探活日志

<RollingFile name="storage_check"
             fileName="${LOG_HOME}/storage_check.log"
             filePattern="${LOG_HOME}/storage_check_%d{yyyy-MM-dd-HH}_%i.log.gz"
             createOnDemand="true">
    <PatternLayout pattern="${LOG_PATTERN}"/>
    <Policies>
        <SizeBasedTriggeringPolicy size="1M"/>
    </Policies>
    <DefaultRolloverStrategy fileIndex="nomax">
        <Delete basePath="${LOG_HOME}" maxDepth="2">
            <IfFileName glob="*.log.gz">
                <IfAny>
                    <IfAccumulatedFileSize exceeds="10M"/>
                    <IfAccumulatedFileCount exceeds="100"/>
                    <IfLastModified age="30d"/>
                </IfAny>
            </IfFileName>
        </Delete>
    </DefaultRolloverStrategy>
</RollingFile>

<logger name="com.zhangziwa.practisesvr.utils.task.StorageHealthyCheckTask" level="info" additivity="false">
    <AppenderRef ref="CONSOLE"/>
    <AppenderRef ref="storage_check"/>
</logger>

第5步:起服务验证
在这里插入图片描述
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要删除Windows系统并恢复MacBook磁盘,可以按照以下步骤进行操作。首先,打开“磁盘工具”,可以看到所有的磁盘。找到Windows系统所在的分区,一般是BOOTCAMP或OSXRERVED,然后点击“抹掉”来删除这个分区。接下来,点击“分区”,选中空白处并点击“-”来删除分区。最后,点击“应用”来保存更改。然而,删除分区后,空出来的空间并没有和主盘合并。为了合并分区,可以使用终端来执行命令。首先,在终端中输入“diskutil list”来查看当前磁盘状况。然后,输入命令“sudo diskutil eraseVolume free none disk0s3”来删除Windows分区,其中“disk0s3”需要根据实际情况替换为对应的BOOT CAMP磁盘盘符。注意,使用终端需要小心核对,确保操作正确。如果还有一个名为“Windows recovery”的分区,也可以使用同样的方法删除。最后,使用磁盘工具来合并磁盘并抹掉Windows操作系统,完成后就可以重新准备安装Windows系统了。 #### 引用[.reference_title] - *1* *3* [苹果系统mac(Air)删除Windows&合并盘(双系统)的可行方案](https://blog.csdn.net/qq_43345641/article/details/100168294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [MacBook如何删除Windows并恢复消除磁盘分区?](https://blog.csdn.net/weixin_44709571/article/details/88069221)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值