package com.wgcloud.task; import cn.hutool.core.collection.CollectionUtil; import com.wgcloud.config.CommonConfig; import com.wgcloud.config.MailConfig; import com.wgcloud.entity.*; import com.wgcloud.service.*; import com.wgcloud.util.DateUtil; import com.wgcloud.util.ServerBackupUtil; import com.wgcloud.util.SnmpUtil; import com.wgcloud.util.ThreadPoolUtil; import com.wgcloud.util.msg.WarnMailUtil; import com.wgcloud.util.msg.WarnPools; import com.wgcloud.util.staticvar.BatchData; import com.wgcloud.util.staticvar.StaticKeys; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.servlet.ServletContext; import java.util.*; /** * @version v3.3 * @ClassName:ScheduledTask.java * @author: http://www.wgstart.com * @date: 2021年1月16日 * @Description: 任务调度执行 * @Copyright: 2019-2021 wgcloud. All rights reserved. */ @Component public class ScheduledTask { private Logger logger = LoggerFactory.getLogger(ScheduledTask.class); @Autowired private SystemInfoService systemInfoService; @Autowired private LogInfoService logInfoService; @Autowired private AppInfoService appInfoService; @Autowired private FileSafeService fileSafeService; @Autowired private DockerInfoService dockerInfoService; @Autowired private PortInfoService portInfoService; @Autowired private MailSetService mailSetService; @Autowired private AccountInfoService accountInfoService; @Autowired private TaskUtilService taskUtilService; @Autowired private CustomInfoService customInfoService; @Autowired private DbTableService dbTableService; @Autowired private DbTableCountService dbTableCountService; @Autowired private HeathMonitorService heathMonitorService; @Autowired private DceInfoService dceInfoService; @Autowired private SnmpInfoService snmpInfoService; @Autowired private CommonConfig commonConfig; @Autowired private MailConfig mailConfig; @Autowired private ServletContext servletContext; /** * 5秒后执行,之后每24小时刷新一次 * 检测license */ @Scheduled(initialDelay = 5000L, fixedRate = 24 * 60 * 60 * 1000) public void validateLicense() { logger.info("validateLicense------------" + DateUtil.getDateTimeString(new Date())); try { servletContext.setAttribute("icoUrl", "/tssw/static/logincss/favicon.png"); servletContext.setAttribute("logoUrl", "/tssw/static/logincss/logo.png"); servletContext.setAttribute("wgName", "WGCLOUD"); servletContext.setAttribute("wgShortName", "WGCLOUD"); //先设置需要显示页面底部版权、网址信息 servletContext.setAttribute("copyRight", "true"); if (!StringUtils.isEmpty(commonConfig.getIcoUrl())) { servletContext.setAttribute("icoUrl", "/tssw/resources/" + commonConfig.getIcoUrl()); } if (!StringUtils.isEmpty(commonConfig.getLogoUrl())) { servletContext.setAttribute("logoUrl", "/tssw/resources/" + commonConfig.getLogoUrl()); } if (!StringUtils.isEmpty(commonConfig.getWgName())) { servletContext.setAttribute("wgName", commonConfig.getWgName()); } if (!StringUtils.isEmpty(commonConfig.getWgShortName())) { servletContext.setAttribute("wgShortName", commonConfig.getWgShortName()); } //是否显示页面底部版权、网址信息,专业版读取配置 servletContext.setAttribute("copyRight", commonConfig.getCopyRight()); } catch (Exception e) { logger.error("检测license任务错误", e); } } /** * 20秒后执行,之后每6分钟刷新一次 * 初始化一些任务 */ @Scheduled(initialDelay = 20000L, fixedRate = 6 * 60 * 1000) public void initTask() { logger.info("initTask------------" + DateUtil.getDateTimeString(new Date())); try { //初始化告警邮件设置 begin Map params = new HashMap(); List list = mailSetService.selectAllByParams(params); if (list.size() > 0) { StaticKeys.mailSet = list.get(0); } else { StaticKeys.mailSet = null; } //初始化告警邮件设置 end //缓存用户账号和用户对象键值对 begin StaticKeys.ACCOUNT_INFO_MAP.clear(); if (StaticKeys.TRUE_VAL.equals(commonConfig.getUserInfoManage())) { List accountInfoList = accountInfoService.selectAllByParams(new HashMap<>()); for (AccountInfo accountInfo : accountInfoList) { StaticKeys.ACCOUNT_INFO_MAP.put(accountInfo.getAccount(), accountInfo); } } //缓存用户账号和用户对象键值对 end //设置是否在告警时间段内,在告警时间段内才发告警 StaticKeys.WARN_CRON_TIME_SIGN = DateUtil.isWarnTime(mailConfig.getWarnCronTime()); } catch (Exception e) { logger.error("initTask错误", e); } } /** * 15秒后执行,之后每小时刷新一次 * 获取所有磁盘总容量之和,缓存起来 */ @Scheduled(initialDelay = 15000L, fixedRate = 60 * 60 * 1000) public void sumDiskSizeCacheTask() { logger.info("sumDiskSizeCacheTask------------" + DateUtil.getDateTimeString(new Date())); try { servletContext.setAttribute("sumDiskSizeCache", taskUtilService.sumDiskSizeCache(null)); } catch (Exception e) { logger.error("获取所有磁盘总容量之和任务错误", e); } } /** * 150秒后执行,之后每隔15分钟执行, 单位:ms。 * snmp设备监测 */ @Scheduled(initialDelay = 150000L, fixedRateString = "${base.snmpTimes}" + "000") public void snmpInfoTask() { if (!StaticKeys.NODE_MASTER.equals(commonConfig.getNodeType())) { logger.info("slave节点不执行snmp设备监测任务"); return; } logger.info("snmpInfoTask------------" + DateUtil.getDateTimeString(new Date())); Map params = new HashMap<>(); Date date = new Date(); try { params.put("active", StaticKeys.ON_STATE); List snmpInfoAllList = snmpInfoService.selectAllByParams(params); if (snmpInfoAllList.size() > 0) { //先组装设备在线状态map,如果不在线就不进行SNMP连接了 Map snmpMap = SnmpUtil.getOnLineList(snmpInfoAllList); for (SnmpInfo h : snmpInfoAllList) { if (ServerBackupUtil.SNMP_INFO_ID_LIST.contains(h.getId())) { logger.info("此设备由wgcloud-server-backup监测:" + h.getHostname()); //将server-backup节点处理的数据,server节点就不监控这些数据了 continue; } Runnable runnable = () -> { snmpInfoService.taskThreadHandler(snmpMap, h, date); }; ThreadPoolUtil.executor.execute(runnable); } } } catch (Exception e) { logger.error("SNMP设备检测任务错误", e); logInfoService.save("SNMP设备检测任务错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 60秒后执行,之后每隔10分钟执行, 单位:ms。 * 检测服务接口 */ @Scheduled(initialDelay = 60000L, fixedRateString = "${base.heathTimes}" + "000") public void heathMonitorTask() { if (!StaticKeys.NODE_MASTER.equals(commonConfig.getNodeType())) { logger.info("slave节点不执行检测服务接口任务"); return; } logger.info("heathMonitorTask------------" + DateUtil.getDateTimeString(new Date())); Map params = new HashMap<>(); Date date = new Date(); try { params.put("active", StaticKeys.ON_STATE); List heathMonitorAllList = heathMonitorService.selectAllByParams(params); if (heathMonitorAllList.size() > 0) { for (HeathMonitor h : heathMonitorAllList) { if (ServerBackupUtil.HEATH_MONITOR_ID_LIST.contains(h.getId())) { logger.info("此接口由wgcloud-server-backup监测:" + h.getAppName()); //将server-backup节点处理的数据,server节点就不监控这些数据了 continue; } Runnable runnable = () -> { // logger.info("HeathMonitor-----------"+h.getHeathUrl()); heathMonitorService.taskThreadHandler(h, date); }; ThreadPoolUtil.executor.execute(runnable); } } } catch (Exception e) { logger.error("服务接口检测任务错误", e); logInfoService.save("服务接口检测错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 90秒后执行,之后每隔15分钟执行, 单位:ms。 * 检测数通PING设备 */ @Scheduled(initialDelay = 90000L, fixedRateString = "${base.dceTimes}" + "000") public void dceInfoTask() { if (!StaticKeys.NODE_MASTER.equals(commonConfig.getNodeType())) { logger.info("slave节点不执行检测数通设备PING任务"); return; } logger.info("dceInfoTask------------" + DateUtil.getDateTimeString(new Date())); Map params = new HashMap<>(); Date date = new Date(); try { params.put("active", StaticKeys.ON_STATE); List dceInfoAllList = dceInfoService.selectAllByParams(params); if (dceInfoAllList.size() > 0) { for (DceInfo h : dceInfoAllList) { if (ServerBackupUtil.DCE_INFO_ID_LIST.contains(h.getId())) { logger.info("此设备由wgcloud-server-backup监测:" + h.getHostname()); //将server-backup节点处理的数据,server节点就不监控这些数据了 continue; } Runnable runnable = () -> { dceInfoService.taskThreadHandler(h, date); }; ThreadPoolUtil.executor.execute(runnable); } } } catch (Exception e) { logger.error("数通设备PING检测任务错误", e); logInfoService.save("数通设备PING检测任务错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 120秒后执行,之后每隔120分钟执行, 单位:ms。 * 数据表监控 */ @Scheduled(initialDelay = 120000L, fixedRateString = "${base.dbTableTimes}" + "000") public void tableCountTask() { if (!StaticKeys.NODE_MASTER.equals(commonConfig.getNodeType())) { logger.info("slave节点不执行数据表监控任务"); return; } logger.info("tableCountTask------------" + DateUtil.getDateTimeString(new Date())); try { dbTableService.taskThreadHandler(); } catch (Exception e) { logger.error("数据表监控任务错误", e); logInfoService.save("数据表监控任务错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 300秒后执行,每6分钟检测一次 * 检测主机是否已经下线,检测进程、端口、docker、文件防篡改是否恢复 */ @Scheduled(initialDelay = 300000L, fixedRate = 5 * 60 * 1000) public void hostDownCheckTask() { if (!StaticKeys.NODE_MASTER.equals(commonConfig.getNodeType())) { logger.info("slave节点不执行检测主机/进程/docker/端口是否恢复任务"); return; } if (DateUtil.isClearTime()) { logger.info("正在清空历史数据,不执行提交检测主机/进程/docker/端口数据----------" + DateUtil.getCurrentDateTime()); BatchData.clearAll(); return; } logger.info("hostDownCheckTask------------" + DateUtil.getDateTimeString(new Date())); checkHostDown(); checkAppDown(); checkDockerDown(); checkPortDown(); checkFileSafeDown(); } /** * 1800秒后执行,之后每120分钟刷新一次 */ /*@Scheduled(initialDelay = 1800000L, fixedRateString = "${base.warnCacheTimes}" + "000") public void initWarnCache() { logger.info("清空告警标记"); WarnPools.clearOldData();//清空发告警邮件的记录 }*/ /** * 检测主机是否下线/恢复 */ private void checkHostDown() { //已下线主机集合 List downHostNameList = new ArrayList<>(); try { Map params = new HashMap(); // params.put("state",StaticKeys.ON_STATE); List list = systemInfoService.selectAllByParams(params); if (!CollectionUtil.isEmpty(list)) { for (SystemInfo systemInfo : list) { //缓存主机IP和主机备注键值对 if (!StringUtils.isEmpty(systemInfo.getRemark())) { StaticKeys.HOST_MAP.put(systemInfo.getHostname(), systemInfo.getRemark()); } //缓存主机IP和用户登录账号键值对 if (StaticKeys.TRUE_VAL.equals(commonConfig.getUserInfoManage()) && !StringUtils.isEmpty(systemInfo.getAccount())) { StaticKeys.HOST_ACCOUNT_MAP.put(systemInfo.getHostname(), systemInfo.getAccount()); } //判断上次提交数据时间和当前时间差 是否超过上报频率时间,考虑数据处理网络等因素额外加90s 超过则判定下线 Date createTime = systemInfo.getCreateTime(); long diff = System.currentTimeMillis() - createTime.getTime(); Integer submitSeconds = (120 + 90) * 1000; try { submitSeconds = (Integer.valueOf(systemInfo.getSubmitSeconds()) + 90) * 1000; } catch (Exception e) { logger.error("Integer转换错误", e); } if (diff >= submitSeconds) { //超时处理 if (null == WarnPools.MEM_WARN_MAP.get(systemInfo.getId())) { downHostNameList.add(systemInfo.getHostname()); } Runnable runnable = () -> { WarnMailUtil.sendHostDown(systemInfo, true); }; ThreadPoolUtil.executor.execute(runnable); } else { //未超时处理 if (null != WarnPools.MEM_WARN_MAP.get(systemInfo.getId())) { Runnable runnable = () -> { WarnMailUtil.sendHostDown(systemInfo, false); }; ThreadPoolUtil.executor.execute(runnable); } } } //标识主机下线 begin if (downHostNameList.size() > 0) { systemInfoService.downByHostName(downHostNameList); //同时标识已下线主机的进程、端口、docker、文件防篡改、自定义监控项都下线 appInfoService.downByHostName(downHostNameList); portInfoService.downByHostName(downHostNameList); dockerInfoService.downByHostName(downHostNameList); fileSafeService.downByHostName(downHostNameList); customInfoService.downByHostName(downHostNameList); } //标识主机下线 end } } catch (Exception e) { logger.error("检测主机是否下线错误", e); logInfoService.save("检测主机是否下线错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 检测进程是否恢复上线 */ private void checkAppDown() { try { Map params = new HashMap(); params.put("state", StaticKeys.ON_STATE); params.put("active", StaticKeys.ON_STATE); List list = appInfoService.selectAllByParams(params); if (!CollectionUtil.isEmpty(list)) { for (AppInfo appInfo : list) { if (null != WarnPools.MEM_WARN_MAP.get(appInfo.getId())) { Runnable runnable = () -> { WarnMailUtil.sendAppDown(appInfo, false); }; ThreadPoolUtil.executor.execute(runnable); } } } } catch (Exception e) { logger.error("检测进程是否恢复错误", e); logInfoService.save("检测进程是否恢复错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 检测docker是否恢复上线 */ private void checkDockerDown() { try { Map params = new HashMap(); params.put("state", StaticKeys.ON_STATE); params.put("active", StaticKeys.ON_STATE); List list = dockerInfoService.selectAllByParams(params); if (!CollectionUtil.isEmpty(list)) { for (DockerInfo appInfo : list) { if (null != WarnPools.MEM_WARN_MAP.get(appInfo.getId())) { Runnable runnable = () -> { WarnMailUtil.sendDockerDown(appInfo, false); }; ThreadPoolUtil.executor.execute(runnable); } } } } catch (Exception e) { logger.error("检测docker是否恢复错误", e); logInfoService.save("检测docker是否恢复错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 检测端口是否恢复上线 */ private void checkPortDown() { try { Map params = new HashMap(); params.put("state", StaticKeys.ON_STATE); params.put("active", StaticKeys.ON_STATE); List list = portInfoService.selectAllByParams(params); if (!CollectionUtil.isEmpty(list)) { for (PortInfo appInfo : list) { if (null != WarnPools.MEM_WARN_MAP.get(appInfo.getId())) { Runnable runnable = () -> { WarnMailUtil.sendPortDown(appInfo, false); }; ThreadPoolUtil.executor.execute(runnable); } } } } catch (Exception e) { logger.error("检测端口是否恢复错误", e); logInfoService.save("检测端口是否恢复错误", e.toString(), StaticKeys.LOG_XTCZ); } } /** * 检测文件防篡改监测是否恢复上线 */ private void checkFileSafeDown() { try { Map params = new HashMap(); params.put("state", StaticKeys.ON_STATE); params.put("active", StaticKeys.ON_STATE); List list = fileSafeService.selectAllByParams(params); if (!CollectionUtil.isEmpty(list)) { for (FileSafe fileSafe : list) { if (null != WarnPools.MEM_WARN_MAP.get(fileSafe.getId())) { Runnable runnable = () -> { WarnMailUtil.sendFileSafeDown(fileSafe, false); }; ThreadPoolUtil.executor.execute(runnable); } } } } catch (Exception e) { logger.error("检测文件防篡改监测是否恢复错误", e); logInfoService.save("检测文件防篡改监测是否恢复错误", e.toString(), StaticKeys.LOG_XTCZ); } } }