From 64baa08aa706d8c33a24e43cb3481cc60d07aa52 Mon Sep 17 00:00:00 2001 From: gaoxq <376340421@qq.com> Date: Mon, 10 Nov 2025 15:03:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...{bizController.java => erpController.java} | 4 +- src/main/java/com/mini/capi/api/startApp.java | 9 ++ .../controller/BizMonitorHostController.java | 18 +++ .../mini/capi/biz/domain/BizMonitorHost.java | 128 ++++++++++++++++++ .../capi/biz/mapper/BizMonitorHostMapper.java | 16 +++ .../biz/service/BizMonitorHostService.java | 16 +++ .../impl/BizMonitorHostServiceImpl.java | 20 +++ .../capi/config/MonitorExecutorConfig.java | 31 +++++ .../com/mini/capi/config/WebMvcConfig.java | 14 ++ .../java/com/mini/capi/job/jobController.java | 60 ++++++++ src/main/java/com/mini/capi/mybatis/demo.java | 2 +- .../com/mini/capi/utils/NetworkUtils.java | 125 +++++++++++++++++ .../resources/mapper/BizMonitorHostMapper.xml | 31 +++++ 13 files changed, 471 insertions(+), 3 deletions(-) rename src/main/java/com/mini/capi/api/biz/{bizController.java => erpController.java} (98%) create mode 100644 src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java create mode 100644 src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java create mode 100644 src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java create mode 100644 src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java create mode 100644 src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java create mode 100644 src/main/java/com/mini/capi/config/MonitorExecutorConfig.java create mode 100644 src/main/java/com/mini/capi/config/WebMvcConfig.java create mode 100644 src/main/java/com/mini/capi/job/jobController.java create mode 100644 src/main/java/com/mini/capi/utils/NetworkUtils.java create mode 100644 src/main/resources/mapper/BizMonitorHostMapper.xml diff --git a/src/main/java/com/mini/capi/api/biz/bizController.java b/src/main/java/com/mini/capi/api/biz/erpController.java similarity index 98% rename from src/main/java/com/mini/capi/api/biz/bizController.java rename to src/main/java/com/mini/capi/api/biz/erpController.java index a646a9a..795fe4a 100644 --- a/src/main/java/com/mini/capi/api/biz/bizController.java +++ b/src/main/java/com/mini/capi/api/biz/erpController.java @@ -15,8 +15,8 @@ import java.math.BigDecimal; import java.time.LocalDateTime; @RestController -@RequestMapping("/bizApi") -public class bizController { +@RequestMapping("/erpApi") +public class erpController { @Resource diff --git a/src/main/java/com/mini/capi/api/startApp.java b/src/main/java/com/mini/capi/api/startApp.java index f390571..705ab0a 100644 --- a/src/main/java/com/mini/capi/api/startApp.java +++ b/src/main/java/com/mini/capi/api/startApp.java @@ -1,4 +1,13 @@ package com.mini.capi.api; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller public class startApp { + + @GetMapping("/") + public String redirectToSwagger() { + return "redirect:/swagger-ui/index.html"; + } } diff --git a/src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java b/src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java new file mode 100644 index 0000000..f8d3152 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/controller/BizMonitorHostController.java @@ -0,0 +1,18 @@ +package com.mini.capi.biz.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 主机信息表 前端控制器 + *

+ * + * @author gaoxq + * @since 2025-11-10 + */ +@RestController +@RequestMapping("/biz/bizMonitorHost") +public class BizMonitorHostController { + +} diff --git a/src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java b/src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java new file mode 100644 index 0000000..9d790e1 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/domain/BizMonitorHost.java @@ -0,0 +1,128 @@ +package com.mini.capi.biz.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 主机信息表 + *

+ * + * @author gaoxq + * @since 2025-11-10 + */ +@Getter +@Setter +@TableName("biz_monitor_host") +public class BizMonitorHost implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 记录创建时间 + */ + @TableField("create_time") + private LocalDateTime createTime; + + /** + * 主机唯一标识(自增主键) + */ + @TableId(value = "host_id", type = IdType.AUTO) + private String hostId; + + /** + * 主机名称 + */ + @TableField("hostname") + private String hostname; + + /** + * IP地址 + */ + @TableField("ip_address") + private String ipAddress; + + /** + * 主机类型 + */ + @TableField("host_type") + private String hostType; + + /** + * 操作系统 + */ + @TableField("host_os") + private String hostOs; + + /** + * 主机状态(1-在线、0-离线、9-维护中) + */ + @TableField("ustatus") + private String ustatus; + + /** + * 最后一次检测到在线的时间 + */ + @TableField("last_online_time") + private LocalDateTime lastOnlineTime; + + /** + * 物理位置 + */ + @TableField("location_name") + private String locationName; + + /** + * 管理人员 + */ + @TableField("admin_user") + private String adminUser; + + /** + * 联系方式 + */ + @TableField("other_contact") + private String otherContact; + + /** + * 备注信息 + */ + @TableField("remark") + private String remark; + + /** + * 记录最后更新时间 + */ + @TableField("update_time") + private LocalDateTime updateTime; + + /** + * 租户id + */ + @TableField("f_tenant_id") + private String fTenantId; + + /** + * 流程id + */ + @TableField("f_flow_id") + private String fFlowId; + + /** + * 流程任务主键 + */ + @TableField("f_flow_task_id") + private String fFlowTaskId; + + /** + * 流程任务状态 + */ + @TableField("f_flow_state") + private Integer fFlowState; +} diff --git a/src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java b/src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java new file mode 100644 index 0000000..6d7491f --- /dev/null +++ b/src/main/java/com/mini/capi/biz/mapper/BizMonitorHostMapper.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.mapper; + +import com.mini.capi.biz.domain.BizMonitorHost; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 主机信息表 Mapper 接口 + *

+ * + * @author gaoxq + * @since 2025-11-10 + */ +public interface BizMonitorHostMapper extends BaseMapper { + +} diff --git a/src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java b/src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java new file mode 100644 index 0000000..bea3776 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/BizMonitorHostService.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.service; + +import com.mini.capi.biz.domain.BizMonitorHost; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 主机信息表 服务类 + *

+ * + * @author gaoxq + * @since 2025-11-10 + */ +public interface BizMonitorHostService extends IService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java b/src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java new file mode 100644 index 0000000..b9f0071 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/impl/BizMonitorHostServiceImpl.java @@ -0,0 +1,20 @@ +package com.mini.capi.biz.service.impl; + +import com.mini.capi.biz.domain.BizMonitorHost; +import com.mini.capi.biz.mapper.BizMonitorHostMapper; +import com.mini.capi.biz.service.BizMonitorHostService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 主机信息表 服务实现类 + *

+ * + * @author gaoxq + * @since 2025-11-10 + */ +@Service +public class BizMonitorHostServiceImpl extends ServiceImpl implements BizMonitorHostService { + +} diff --git a/src/main/java/com/mini/capi/config/MonitorExecutorConfig.java b/src/main/java/com/mini/capi/config/MonitorExecutorConfig.java new file mode 100644 index 0000000..ca25bf9 --- /dev/null +++ b/src/main/java/com/mini/capi/config/MonitorExecutorConfig.java @@ -0,0 +1,31 @@ +package com.mini.capi.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync // 启用异步任务支持 +public class MonitorExecutorConfig { + + /** + * 配置主机监控专用线程池 + */ + @Bean(name = "hostMonitorExecutor") + public ThreadPoolTaskExecutor hostMonitorExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + int corePoolSize = Runtime.getRuntime().availableProcessors(); + executor.setCorePoolSize(corePoolSize); + executor.setMaxPoolSize(corePoolSize * 2); + executor.setQueueCapacity(200); + executor.setKeepAliveSeconds(60); + executor.setThreadNamePrefix("Host-Monitor-"); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + executor.initialize(); + return executor; + } +} diff --git a/src/main/java/com/mini/capi/config/WebMvcConfig.java b/src/main/java/com/mini/capi/config/WebMvcConfig.java new file mode 100644 index 0000000..656aebd --- /dev/null +++ b/src/main/java/com/mini/capi/config/WebMvcConfig.java @@ -0,0 +1,14 @@ +package com.mini.capi.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +@Configuration +public class WebMvcConfig implements WebMvcConfigurer{ + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + // 访问根路径 "/" 时,自动重定向到 Swagger UI + registry.addRedirectViewController("/", "/swagger-ui/index.html"); + } +} diff --git a/src/main/java/com/mini/capi/job/jobController.java b/src/main/java/com/mini/capi/job/jobController.java new file mode 100644 index 0000000..f0fb801 --- /dev/null +++ b/src/main/java/com/mini/capi/job/jobController.java @@ -0,0 +1,60 @@ +package com.mini.capi.job; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.mini.capi.biz.domain.BizMonitorHost; +import com.mini.capi.biz.service.BizMonitorHostService; +import com.mini.capi.utils.NetworkUtils; +import jakarta.annotation.Resource; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Controller; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +@Controller +public class jobController { + + + @Resource + private BizMonitorHostService bizMonitorHostService; + + // 注入配置好的线程池 + @Resource(name = "hostMonitorExecutor") + private ThreadPoolTaskExecutor hostMonitorExecutor; + + /** + * + */ + @Scheduled(cron = "0 0/10 * * * ?") + public void getJobMonitHostStatus() { + List monitorHosts = bizMonitorHostService.list(); + List> futures = new ArrayList<>(monitorHosts.size()); + for (BizMonitorHost monitorHost : monitorHosts) { + CompletableFuture future = CompletableFuture.runAsync(() -> { + try { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("host_id", monitorHost.getHostId()); + boolean isReachable = NetworkUtils.isNetworkReachable(monitorHost.getIpAddress()); + monitorHost.setUstatus(isReachable ? "1" : "0"); + if (isReachable) { + monitorHost.setLastOnlineTime(LocalDateTime.now()); + } + bizMonitorHostService.update(monitorHost, updateWrapper); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + }, hostMonitorExecutor); // 指定使用配置的线程池 + futures.add(future); + } + try { + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) + .get(60, TimeUnit.SECONDS); // 超时时间可根据业务调整 + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } +} diff --git a/src/main/java/com/mini/capi/mybatis/demo.java b/src/main/java/com/mini/capi/mybatis/demo.java index a27b6f4..78235a7 100644 --- a/src/main/java/com/mini/capi/mybatis/demo.java +++ b/src/main/java/com/mini/capi/mybatis/demo.java @@ -29,7 +29,7 @@ public class demo { .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "/src/main/resources/mapper")); }) .strategyConfig(builder -> { - builder.addInclude("biz_cities,biz_company,biz_mail_account,biz_project_info,biz_project_requirements,biz_province,biz_resume_employee,erp_transfer,biz_website_storage,erp_period_summary,biz_municipalities,erp_account,erp_transaction_flow,erp_expense,erp_category,erp_income,biz_project_report,biz_mail_sent") + builder.addInclude("biz_monitor_host") .addTablePrefix("biz_,erp_") .entityBuilder() .enableLombok() diff --git a/src/main/java/com/mini/capi/utils/NetworkUtils.java b/src/main/java/com/mini/capi/utils/NetworkUtils.java new file mode 100644 index 0000000..3f399ff --- /dev/null +++ b/src/main/java/com/mini/capi/utils/NetworkUtils.java @@ -0,0 +1,125 @@ +package com.mini.capi.utils; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +/** + * 网络连通性检测工具类(支持IPv4和域名) + */ +public class NetworkUtils { + + // IPv4地址校验正则(支持带前后空白) + private static final Pattern IPV4_PATTERN = Pattern.compile( + "^\\s*((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\s*$" + ); + + // Ping命令配置常量 + private static final int PING_COUNT = 2; + private static final int WINDOWS_TIMEOUT_MS = 3000; + private static final int LINUX_TIMEOUT_SEC = 3; + private static final int PROCESS_WAIT_TIMEOUT_SEC = 6; + + // 私有构造器:禁止实例化 + private NetworkUtils() { + throw new AssertionError("工具类不允许实例化"); + } + + /** + * 检测本地网络到目标IP或域名的连通性 + */ + public static boolean isNetworkReachable(String target) { + if (target == null || target.trim().isEmpty()) { + return false; + } + target = target.trim(); + + List ipList = new ArrayList<>(); + // 区分IP和域名,解析目标为IP列表 + if (isValidIpv4(target)) { + ipList.add(target); // 是IP,直接加入 + } else { + // 是域名,尝试解析为IP + try { + InetAddress[] addresses = InetAddress.getAllByName(target); + for (InetAddress addr : addresses) { + ipList.add(addr.getHostAddress()); + } + if (ipList.isEmpty()) { + return false; // 域名解析无结果 + } + } catch (UnknownHostException e) { + return false; // 域名无法解析(如不存在、网络故障) + } + } + + // 对每个IP执行ping检测,有一个成功则返回true + for (String ip : ipList) { + if (executePingCommand(buildPingCommand(ip))) { + return true; + } + } + return false; + } + + /** + * 校验是否为合法的IPv4地址(支持带前后空白) + */ + private static boolean isValidIpv4(String ip) { + return IPV4_PATTERN.matcher(ip).matches(); + } + + /** + * 构建跨系统的ping命令 + */ + private static List buildPingCommand(String ip) { + List command = new ArrayList<>(5); + command.add("ping"); + + String osName = System.getProperty("os.name", "").toLowerCase(); + if (osName.contains("windows")) { + command.add("-n"); + command.add(String.valueOf(PING_COUNT)); + command.add("-w"); + command.add(String.valueOf(WINDOWS_TIMEOUT_MS)); + } else { + command.add("-c"); + command.add(String.valueOf(PING_COUNT)); + command.add("-W"); + command.add(String.valueOf(LINUX_TIMEOUT_SEC)); + } + + command.add(ip); + return command; + } + + /** + * 执行ping命令并返回执行结果 + */ + private static boolean executePingCommand(List command) { + Process process = null; + try { + ProcessBuilder processBuilder = new ProcessBuilder(command); + processBuilder.redirectErrorStream(true); + process = processBuilder.start(); + + boolean isFinished = process.waitFor(PROCESS_WAIT_TIMEOUT_SEC, TimeUnit.SECONDS); + if (!isFinished) { + process.destroyForcibly(); + return false; + } + return process.exitValue() == 0; + + } catch (IOException | InterruptedException e) { + return false; + } finally { + if (process != null) { + process.destroyForcibly(); + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/mapper/BizMonitorHostMapper.xml b/src/main/resources/mapper/BizMonitorHostMapper.xml new file mode 100644 index 0000000..fc7362a --- /dev/null +++ b/src/main/resources/mapper/BizMonitorHostMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + create_time, host_id, hostname, ip_address, host_type, host_os, ustatus, last_online_time, location_name, admin_user, other_contact, remark, update_time, f_tenant_id, f_flow_id, f_flow_task_id, f_flow_state + + +