From 6538f32cbf7ccfa98530e13f56505f6da37d2ca5 Mon Sep 17 00:00:00 2001 From: Mzaxd Date: Sat, 11 Mar 2023 23:12:08 +0800 Subject: [PATCH] =?UTF-8?q?[Improvement]=E9=80=9A=E8=BF=87=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E5=A4=9A=E7=BA=BF=E7=A8=8B=E7=9A=84=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E5=A4=A7=E5=B9=85=E7=BC=A9=E7=9F=AD=E4=BA=86=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=E6=8E=89=E7=BA=BF=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD=E7=9A=84?= =?UTF-8?q?=E5=8D=95=E6=AC=A1=E6=89=A7=E8=A1=8C=E8=80=97=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../noodles/job/CheckInstancesStatus.java | 107 ++++-- .../java/com/mzaxd/noodles/util/CpuUtil.java | 19 + .../noodles/NoodlesApplicationTests.java | 326 +++++++++++++++++- 3 files changed, 414 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/mzaxd/noodles/util/CpuUtil.java diff --git a/src/main/java/com/mzaxd/noodles/job/CheckInstancesStatus.java b/src/main/java/com/mzaxd/noodles/job/CheckInstancesStatus.java index 6d313b4..cb67e9a 100644 --- a/src/main/java/com/mzaxd/noodles/job/CheckInstancesStatus.java +++ b/src/main/java/com/mzaxd/noodles/job/CheckInstancesStatus.java @@ -10,6 +10,7 @@ import com.mzaxd.noodles.domain.entity.Container; import com.mzaxd.noodles.domain.entity.HostDetector; import com.mzaxd.noodles.domain.entity.HostMachine; import com.mzaxd.noodles.service.*; +import com.mzaxd.noodles.util.CpuUtil; import com.mzaxd.noodles.util.RedisCache; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; @@ -22,15 +23,17 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.concurrent.*; /** * 检测所有实例的在线状态 + * * @author 13439 */ @Slf4j @Component -public class CheckInstancesStatus{ +public class CheckInstancesStatus { @Resource private ContainerService containerService; @@ -50,43 +53,77 @@ public class CheckInstancesStatus{ /** * 检查实例状态并且发送对应的提醒 */ - @Scheduled(cron = "* 0/10 * * * ?") + @Scheduled(cron = "* 0/1 * * * ?") public void checkInstancesStatus() { - //检测容器在线状态 List containers = containerService.list(); - containers.forEach(container -> { - try { - if (!StringUtils.hasText(container.getWebUi())) { - container.setContainerState(SystemConstant.CONTAINER_STATE_UNKNOWN); - return; - } - HttpRequest.get(container.getWebUi()).setConnectionTimeout(1000).execute(true); - log.info("[实例状态检测]:与{}建立连接成功", container.getName()); - container.setContainerState(SystemConstant.CONTAINER_STATE_RUNNING); - } catch (Exception exception) { - log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", container.getName()); - container.setContainerState(SystemConstant.CONTAINER_STATE_EXITED); - //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 - Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS); - if (!CollectionUtils.isEmpty(set)){ - //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 - if (set.contains(container.getId().toString())) { - return; - } else { - //根据实例对应的提醒方式进行提醒 - if (container.getNotify().equals(SystemConstant.NOTIFY_NO)) { - return; + int thread = CpuUtil.getLogicProcessorCount(); + int containerCount = containerService.count(); + int corePoolSize = Math.min(thread + 1, containerCount); + int maxPoolSize = Math.max(thread + 1, containerCount); + + // 创建一个包含10个线程的线程池 + ExecutorService executor = new ThreadPoolExecutor( + corePoolSize, + maxPoolSize, + 1, + TimeUnit.SECONDS, + new LinkedBlockingQueue<>(), + new ThreadPoolExecutor.AbortPolicy()); + + // 创建一个 Future 列表,用于存储每个容器检查的结果 + List> futures = new ArrayList<>(); + + for (Container container : containers) { + futures.add(executor.submit(() -> { + try { + if (!StringUtils.hasText(container.getWebUi())) { + container.setContainerState(SystemConstant.CONTAINER_STATE_UNKNOWN); + return container; + } + HttpRequest.get(container.getWebUi()).setConnectionTimeout(5000).execute(true); + log.info("[实例状态检测]:与{}建立连接成功", container.getName()); + container.setContainerState(SystemConstant.CONTAINER_STATE_RUNNING); + } catch (Exception exception) { + log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", container.getName()); + container.setContainerState(SystemConstant.CONTAINER_STATE_EXITED); + // 判断 Redis 里面有没有,如果有就不需要提醒,如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS); + if (!CollectionUtils.isEmpty(set)) { + // 如果 Redis 里面有,说明已经发送过了未 check 的通知,所以不需要发送,直接返回 + if (set.contains(container.getId().toString())) { + return container; } else { - notificationService.sendContainerOfflineNotification(container.getId()); + // 根据实例对应的提醒方式进行提醒 + if (container.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return container; + } else { + notificationService.sendContainerOfflineNotification(container.getId()); + } } } + // 存入 Redis + set.add(container.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS, set); } - //存入redis - set.add(container.getId().toString()); - redisCache.setCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS, set); + return container; + })); + } + + // 等待所有线程执行完成,并收集更新后的容器列表 + List updatedContainers = new ArrayList<>(); + for (Future future : futures) { + try { + Container container = future.get(); + updatedContainers.add(container); + } catch (InterruptedException | ExecutionException e) { + log.error("检查容器状态时出错:{}", e.getMessage()); } - }); - containerService.saveOrUpdateBatch(containers); + } + + // 将更新后的容器列表保存到数据库中 + containerService.saveOrUpdateBatch(updatedContainers); + // 关闭线程池 + executor.shutdown(); //检测虚拟机在线状态 LambdaQueryWrapper vmWrapper = new LambdaQueryWrapper<>(); @@ -98,7 +135,7 @@ public class CheckInstancesStatus{ vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_UNKNOWN); return; } - HttpRequest.get(vm.getManageIp()).setConnectionTimeout(1000).execute(true); + HttpRequest.get(vm.getManageIp()).setConnectionTimeout(5000).execute(true); log.info("[实例状态检测]:与{}建立连接成功", vm.getName()); vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_ONLINE); } catch (Exception exception) { @@ -106,7 +143,7 @@ public class CheckInstancesStatus{ vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_OFFLINE); //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_VM_IDS); - if (!CollectionUtils.isEmpty(set)){ + if (!CollectionUtils.isEmpty(set)) { //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 if (set.contains(vm.getId().toString())) { return; @@ -132,7 +169,7 @@ public class CheckInstancesStatus{ List hostMachines = new ArrayList<>(); hostDetectors.forEach(detector -> { try { - HttpRequest.get(detector.getDetectorIpAddress() + UrlConstant.DETECTOR_IS_TRUE_URL).setConnectionTimeout(1000).execute(true); + HttpRequest.get(detector.getDetectorIpAddress() + UrlConstant.DETECTOR_IS_TRUE_URL).setConnectionTimeout(5000).execute(true); HostMachine hostMachine = hostMachineService.getById(detector.getHostMachineId()); if (Objects.nonNull(hostMachine)) { hostMachine.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_ONLINE); @@ -146,7 +183,7 @@ public class CheckInstancesStatus{ } //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_HOST_IDS); - if (!CollectionUtils.isEmpty(set)){ + if (!CollectionUtils.isEmpty(set)) { //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 if (set.contains(hostMachine.getId().toString())) { return; diff --git a/src/main/java/com/mzaxd/noodles/util/CpuUtil.java b/src/main/java/com/mzaxd/noodles/util/CpuUtil.java new file mode 100644 index 0000000..7c97341 --- /dev/null +++ b/src/main/java/com/mzaxd/noodles/util/CpuUtil.java @@ -0,0 +1,19 @@ +package com.mzaxd.noodles.util; + +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.HardwareAbstractionLayer; + +/** + * @author Mzaxd + * @since 2023-03-11 22:17 + */ +public class CpuUtil { + + public static int getLogicProcessorCount() { + SystemInfo systemInfo = new SystemInfo(); + HardwareAbstractionLayer hardware = systemInfo.getHardware(); + CentralProcessor processor = hardware.getProcessor(); + return processor.getLogicalProcessorCount(); + } +} diff --git a/src/test/java/com/mzaxd/noodles/NoodlesApplicationTests.java b/src/test/java/com/mzaxd/noodles/NoodlesApplicationTests.java index 47b165e..fab0693 100644 --- a/src/test/java/com/mzaxd/noodles/NoodlesApplicationTests.java +++ b/src/test/java/com/mzaxd/noodles/NoodlesApplicationTests.java @@ -8,10 +8,13 @@ import cn.hutool.http.HttpException; import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.mzaxd.noodles.constant.RedisConstant; import com.mzaxd.noodles.constant.SystemConstant; +import com.mzaxd.noodles.constant.UrlConstant; import com.mzaxd.noodles.domain.entity.*; import com.mzaxd.noodles.mapper.OsMapper; import com.mzaxd.noodles.service.*; +import com.mzaxd.noodles.util.CpuUtil; import com.mzaxd.noodles.util.RedisCache; import com.mzaxd.noodles.util.SystemInfoUtils; import lombok.extern.slf4j.Slf4j; @@ -19,10 +22,12 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import javax.annotation.Resource; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.concurrent.*; @Slf4j @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -40,6 +45,12 @@ class NoodlesApplicationTests { @Resource private SystemSettingService systemSettingService; + @Resource + private NotificationService notificationService; + + @Resource + private HostDetectorService hostDetectorService; + @Test void contextLoads() { try { @@ -65,7 +76,7 @@ class NoodlesApplicationTests { account.setFrom(systemSetting.getNotificationEmail()); account.setUser(systemSetting.getNotificationEmail()); account.setPass(systemSetting.getEmailPass()); - MailUtil.send(account, CollUtil.newArrayList("mzaxd0712@gmail.com"),"测试5","邮件来自测试",false); + MailUtil.send(account, CollUtil.newArrayList("mzaxd0712@gmail.com"), "测试5", "邮件来自测试", false); } @Test @@ -132,4 +143,313 @@ class NoodlesApplicationTests { System.out.println(everyDayData); } + + @Test + public void checkInstanceStatus() { + long startTime = System.nanoTime(); // 记录开始时间 + + //检测容器在线状态 + List containers = containerService.list(); + containers.forEach(container -> { + try { + if (!StringUtils.hasText(container.getWebUi())) { + container.setContainerState(SystemConstant.CONTAINER_STATE_UNKNOWN); + return; + } + HttpRequest.get(container.getWebUi()).setConnectionTimeout(1000).execute(true); + log.info("[实例状态检测]:与{}建立连接成功", container.getName()); + container.setContainerState(SystemConstant.CONTAINER_STATE_RUNNING); + } catch (Exception exception) { + log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", container.getName()); + container.setContainerState(SystemConstant.CONTAINER_STATE_EXITED); + //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS); + if (!CollectionUtils.isEmpty(set)) { + //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 + if (set.contains(container.getId().toString())) { + return; + } else { + //根据实例对应的提醒方式进行提醒 + if (container.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return; + } else { + notificationService.sendContainerOfflineNotification(container.getId()); + } + } + } + //存入redis + set.add(container.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS, set); + } + }); + containerService.saveOrUpdateBatch(containers); + + //检测虚拟机在线状态 + LambdaQueryWrapper vmWrapper = new LambdaQueryWrapper<>(); + vmWrapper.ne(HostMachine::getHostMachineId, SystemConstant.HOST_MACHINE_ID_HOST); + List vms = hostMachineService.list(vmWrapper); + vms.forEach(vm -> { + try { + if (!StringUtils.hasText(vm.getManageIp())) { + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_UNKNOWN); + return; + } + HttpRequest.get(vm.getManageIp()).setConnectionTimeout(1000).execute(true); + log.info("[实例状态检测]:与{}建立连接成功", vm.getName()); + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_ONLINE); + } catch (Exception exception) { + log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", vm.getName()); + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_OFFLINE); + //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_VM_IDS); + if (!CollectionUtils.isEmpty(set)) { + //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 + if (set.contains(vm.getId().toString())) { + return; + } else { + //根据实例对应的提醒方式进行提醒 + if (vm.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return; + } else { + notificationService.sendVmOfflineNotification(vm.getId()); + } + } + } + //存入redis + set.add(vm.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_VM_IDS, set); + } + }); + hostMachineService.saveOrUpdateBatch(vms); + + //检测物理机在线状态(检测物理机要用探测器的isTureUrl接口) + LambdaQueryWrapper detectorWrapper = new LambdaQueryWrapper<>(); + List hostDetectors = hostDetectorService.list(detectorWrapper); + List hostMachines = new ArrayList<>(); + hostDetectors.forEach(detector -> { + try { + HttpRequest.get(detector.getDetectorIpAddress() + UrlConstant.DETECTOR_IS_TRUE_URL).setConnectionTimeout(1000).execute(true); + HostMachine hostMachine = hostMachineService.getById(detector.getHostMachineId()); + if (Objects.nonNull(hostMachine)) { + hostMachine.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_ONLINE); + hostMachines.add(hostMachine); + } + } catch (Exception exception) { + HostMachine hostMachine = hostMachineService.getById(detector.getHostMachineId()); + if (Objects.nonNull(hostMachine)) { + hostMachine.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_OFFLINE); + hostMachines.add(hostMachine); + } + //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_HOST_IDS); + if (!CollectionUtils.isEmpty(set)) { + //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 + if (set.contains(hostMachine.getId().toString())) { + return; + } else { + //根据实例对应的提醒方式进行提醒 + if (hostMachine.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return; + } else { + notificationService.sendHostOfflineNotification(hostMachine.getId()); + } + } + } + //存入redis + set.add(hostMachine.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_HOST_IDS, set); + } + }); + hostMachineService.saveOrUpdateBatch(hostMachines); + + long endTime = System.nanoTime(); // 记录结束时间 + long elapsedTime = endTime - startTime; + double seconds = (double) elapsedTime / 1_000_000_000.0; // 将纳秒转换为秒 + System.out.println("代码执行时间:" + seconds + " 秒"); + } + + @Test + public void checkContainerStatusMultiThread() { + long startTime = System.nanoTime(); // 记录开始时间 + + List containers = containerService.list(); + int thread = CpuUtil.getLogicProcessorCount(); + int containerCount = containerService.count(); + + int corePoolSize = Math.min(thread + 1, containerCount); + int maxPoolSize = Math.max(thread + 1, containerCount); + + // 创建一个包含10个线程的线程池 + ExecutorService executor = new ThreadPoolExecutor( + corePoolSize, + maxPoolSize, + 1, + TimeUnit.SECONDS, + new LinkedBlockingQueue<>(), + new ThreadPoolExecutor.AbortPolicy()); + + // 创建一个 Future 列表,用于存储每个容器检查的结果 + List> futures = new ArrayList<>(); + + for (Container container : containers) { + futures.add(executor.submit(() -> { + try { + if (!StringUtils.hasText(container.getWebUi())) { + container.setContainerState(SystemConstant.CONTAINER_STATE_UNKNOWN); + return container; + } + HttpRequest.get(container.getWebUi()).setConnectionTimeout(5000).execute(true); + log.info("[实例状态检测]:与{}建立连接成功", container.getName()); + container.setContainerState(SystemConstant.CONTAINER_STATE_RUNNING); + } catch (Exception exception) { + log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", container.getName()); + container.setContainerState(SystemConstant.CONTAINER_STATE_EXITED); + // 判断 Redis 里面有没有,如果有就不需要提醒,如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS); + if (!CollectionUtils.isEmpty(set)) { + // 如果 Redis 里面有,说明已经发送过了未 check 的通知,所以不需要发送,直接返回 + if (set.contains(container.getId().toString())) { + return container; + } else { + // 根据实例对应的提醒方式进行提醒 + if (container.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return container; + } else { + notificationService.sendContainerOfflineNotification(container.getId()); + } + } + } + // 存入 Redis + set.add(container.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_CONTAINER_IDS, set); + } + return container; + })); + } + + // 等待所有线程执行完成,并收集更新后的容器列表 + List updatedContainers = new ArrayList<>(); + for (Future future : futures) { + try { + Container container = future.get(); + updatedContainers.add(container); + } catch (InterruptedException | ExecutionException e) { + log.error("检查容器状态时出错:{}", e.getMessage()); + } + } + + // 将更新后的容器列表保存到数据库中 + containerService.saveOrUpdateBatch(updatedContainers); + + // 关闭线程池 + executor.shutdown(); + + long endTime = System.nanoTime(); // 记录结束时间 + long elapsedTime = endTime - startTime; + double seconds = (double) elapsedTime / 1_000_000_000.0; // 将纳秒转换为秒 + System.out.println("代码执行时间:" + seconds + " 秒"); + } + + + @Test + public void checkVmStatus() { + long startTime = System.nanoTime(); // 记录开始时间 + + //检测虚拟机在线状态 + LambdaQueryWrapper vmWrapper = new LambdaQueryWrapper<>(); + vmWrapper.ne(HostMachine::getHostMachineId, SystemConstant.HOST_MACHINE_ID_HOST); + List vms = hostMachineService.list(vmWrapper); + vms.forEach(vm -> { + try { + if (!StringUtils.hasText(vm.getManageIp())) { + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_UNKNOWN); + return; + } + HttpRequest.get(vm.getManageIp()).setConnectionTimeout(5000).execute(true); + log.info("[实例状态检测]:与{}建立连接成功", vm.getName()); + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_ONLINE); + } catch (Exception exception) { + log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", vm.getName()); + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_OFFLINE); + //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_VM_IDS); + if (!CollectionUtils.isEmpty(set)) { + //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 + if (set.contains(vm.getId().toString())) { + return; + } else { + //根据实例对应的提醒方式进行提醒 + if (vm.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return; + } else { + notificationService.sendVmOfflineNotification(vm.getId()); + } + } + } + //存入redis + set.add(vm.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_VM_IDS, set); + } + }); + hostMachineService.saveOrUpdateBatch(vms); + + long endTime = System.nanoTime(); // 记录结束时间 + long elapsedTime = endTime - startTime; + double seconds = (double) elapsedTime / 1_000_000_000.0; // 将纳秒转换为秒 + System.out.println("代码执行时间:" + seconds + " 秒"); + } + + + @Test + public void checkVmStatusMultiThread() throws InterruptedException { + long startTime = System.nanoTime(); // 记录开始时间 + + ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建一个线程池 + List vms = hostMachineService.list(); // 获取所有主机列表 + CountDownLatch countDownLatch = new CountDownLatch(vms.size()); // 用于等待所有线程完成 + for (HostMachine vm : vms) { + executorService.submit(() -> { + try { + if (!StringUtils.hasText(vm.getManageIp())) { + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_UNKNOWN); + return; + } + HttpRequest.get(vm.getManageIp()).setConnectionTimeout(5000).execute(true); + log.info("[实例状态检测]:与{}建立连接成功", vm.getName()); + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_ONLINE); + } catch (Exception exception) { + log.info("[实例状态检测]:与{}建立连接失败,状态转为离线", vm.getName()); + vm.setHostMachineState(SystemConstant.HOST_MACHINE_STATE_OFFLINE); + //判断Redis里面有没有 如果有就不需要提醒 如果没有就提醒 + Set set = redisCache.getCacheSet(RedisConstant.NOTIFY_VM_IDS); + if (!CollectionUtils.isEmpty(set)) { + //如果redis里面有 说明已经发送过了未check的通知 所以不需要发送 直接返回 + if (set.contains(vm.getId().toString())) { + return; + } else { + //根据实例对应的提醒方式进行提醒 + if (vm.getNotify().equals(SystemConstant.NOTIFY_NO)) { + return; + } else { + notificationService.sendVmOfflineNotification(vm.getId()); + } + } + } + //存入redis + set.add(vm.getId().toString()); + redisCache.setCacheSet(RedisConstant.NOTIFY_VM_IDS, set); + } finally { + countDownLatch.countDown(); // 完成一个线程 + } + }); + } + countDownLatch.await(); // 等待所有线程完成 + hostMachineService.saveOrUpdateBatch(vms); // 保存更新后的主机状态 + executorService.shutdown(); // 关闭线程池 + + long endTime = System.nanoTime(); // 记录结束时间 + long elapsedTime = endTime - startTime; + double seconds = (double) elapsedTime / 1_000_000_000.0; // 将纳秒转换为秒 + System.out.println("代码执行时间:" + seconds + " 秒"); + } }