茂名小学网站建设,德国室内设计联盟,群晖wordpress打不开,公司展厅主盘探活通常是指检查存储设备#xff08;例如硬盘#xff09;是否可读写#xff0c;但在Java中并没有直接针对硬件级别的磁盘探活API。然而#xff0c;我们可以模拟一个场景#xff0c;即检查某个目录或文件是否可以被Java程序正常读写#xff0c;以此作为主盘活跃的一个… 主盘探活通常是指检查存储设备例如硬盘是否可读写但在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 {FutureBoolean 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\testneedCheck: 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 namestorage_checkfileName${LOG_HOME}/storage_check.logfilePattern${LOG_HOME}/storage_check_%d{yyyy-MM-dd-HH}_%i.log.gzcreateOnDemandtruePatternLayout pattern${LOG_PATTERN}/PoliciesSizeBasedTriggeringPolicy size1M//PoliciesDefaultRolloverStrategy fileIndexnomaxDelete basePath${LOG_HOME} maxDepth2IfFileName glob*.log.gzIfAnyIfAccumulatedFileSize exceeds10M/IfAccumulatedFileCount exceeds100/IfLastModified age30d//IfAny/IfFileName/Delete/DefaultRolloverStrategy
/RollingFilelogger namecom.zhangziwa.practisesvr.utils.task.StorageHealthyCheckTask levelinfo additivityfalseAppenderRef refCONSOLE/AppenderRef refstorage_check/
/logger第5步起服务验证