feat:使用spring定时任务替换quartz

This commit is contained in:
nieziyan 2024-02-26 19:37:25 +08:00
parent 6d26adccaf
commit 1cb2f68428
15 changed files with 486 additions and 140 deletions

View File

@ -18,12 +18,6 @@ import io.swagger.annotations.Api;
@RequestMapping("nuclideParam")
public class AlarmAnalysisNuclideParamController extends JeecgController<AlarmAnalysisNuclideParam, IAlarmAnalysisNuclideParamService> {
@GetMapping("refresh")
@ApiOperation(value = "定时刷新核素计算参数信息",notes = "定时刷新核素计算参数信息")
public boolean refreshParam(){
return service.refresh();
}
@GetMapping("findInfo")
@ApiOperation(value = "回显核素计算参数信息",notes = "回显核素计算参数信息")
public Result findInfo(){

View File

@ -1,26 +0,0 @@
package org.jeecg.modules.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.modules.service.CalculateConcService;
import org.jeecg.modules.service.IAlarmAnalysisNuclideParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(value = "定时计算核素浓度" ,tags="定时计算核素浓度")
@RestController
@RequestMapping("calculateConc")
public class CalculateConcController {
@Autowired
private CalculateConcService calculateConcService;
@GetMapping("caclAndSave")
@ApiOperation(value = "计算并保存核素浓度",notes = "计算并保存核素浓度")
public boolean caclAndSave(){
return calculateConcService.calcAndSave();
}
}

View File

@ -0,0 +1,6 @@
package org.jeecg.modules.job;
public interface Job {
void execute();
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.job;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.service.IAlarmAnalysisNuclideParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class NuclideParamJob implements Job{
@Autowired
private IAlarmAnalysisNuclideParamService nuclideParamService;
@Override
@Scheduled(cron = "${task.period-param:0 1 0 * * ?}")
public void execute() { nuclideParamService.refresh(); }
}

View File

@ -0,0 +1,21 @@
package org.jeecg.modules.job;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.service.CalculateConcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class NucliedAvgJob implements Job{
@Autowired
private CalculateConcService calculateConcService;
@Override
@Scheduled(cron = "${task.period-avg:0 2 0 * * ?}")
public void execute() {
calculateConcService.calcAndSave();
}
}

View File

@ -8,7 +8,7 @@ import java.util.Map;
public interface CalculateConcService {
boolean calcAndSave();
void calcAndSave();
Map<String, String> calculate(List<ConcDto> concDtos, BigDecimal index);
}

View File

@ -7,7 +7,7 @@ public interface IAlarmAnalysisNuclideParamService extends IService<AlarmAnalysi
AlarmAnalysisNuclideParam getLatest();
boolean refresh();
void refresh();
boolean update(AlarmAnalysisNuclideParam nuclideParam);
}

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.base.entity.postgre.AlarmAnalysisNuclideParam;
import org.jeecg.modules.mapper.AlarmAnalysisNuclideParamMapper;
import org.jeecg.modules.service.IAlarmAnalysisNuclideParamService;
@ -13,6 +14,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.time.LocalDate;
import java.time.ZoneId;
@Slf4j
@Service
public class AlarmAnalysisNuclideParamServiceImpl extends ServiceImpl<AlarmAnalysisNuclideParamMapper, AlarmAnalysisNuclideParam> implements IAlarmAnalysisNuclideParamService {
@ -24,7 +26,7 @@ public class AlarmAnalysisNuclideParamServiceImpl extends ServiceImpl<AlarmAnaly
}
@Override
public boolean refresh() {
public void refresh() {
try {
AlarmAnalysisNuclideParam nuclideParam = new AlarmAnalysisNuclideParam();
AlarmAnalysisNuclideParam latest = getLatest();
@ -32,14 +34,16 @@ public class AlarmAnalysisNuclideParamServiceImpl extends ServiceImpl<AlarmAnaly
.atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate today = LocalDate.now();
boolean isToday = today.equals(localDate);
if (isToday) return true;
if (isToday) return;
CopyOptions options = CopyOptions.create()
.setIgnoreProperties("id","createTime");
BeanUtil.copyProperties(latest,nuclideParam,options);
return save(nuclideParam);
}catch (Throwable e){
e.printStackTrace();
return false;
save(nuclideParam);
// log记录
log.info("NuclideParamJob执行成功, 当前核素参数: [days: {},index: {}]",
nuclideParam.getDays(), nuclideParam.getIndex());
}catch (Exception e){
log.error("NuclideParamJob执行异常: {}", e.getMessage());
}
}

View File

@ -24,8 +24,8 @@ import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Slf4j
@Service
public class CalculateConcServiceImpl implements CalculateConcService {
@Autowired
@ -50,7 +50,7 @@ public class CalculateConcServiceImpl implements CalculateConcService {
private IAlarmAnalysisNuclideParamService nuclideParamService;
@Override
public boolean calcAndSave() {
public void calcAndSave() {
try {
String comma = SymbolConstant.COMMA;
// 获取所有生效的报警规则
@ -138,14 +138,11 @@ public class CalculateConcServiceImpl implements CalculateConcService {
// 计算周期和计算日期
String cycle = startDate + SymbolConstant.WELL_NUMBER + endDate;
allAvgs.forEach(item -> item.setCycle(cycle).setCaclDate(dayAgo));
nuclideAvgService.saveBatch(allAvgs);
// 记录日志
log.info(log(allAvgs));
return nuclideAvgService.saveBatch(allAvgs);
}catch (Throwable e){
e.printStackTrace();
log.error("核素浓度计算过程异常: {}", e.getMessage());
return false;
}catch (Exception e){
log.error("NucliedAvgJob执行异常: {}", e.getMessage());
}
}

View File

@ -29,14 +29,6 @@ public interface AbnormalAlarmClient {
@PostMapping("/alarmLog/create")
Result<?> create(@RequestBody AlarmLog alarmLog);
/* CalculateConcController下相关接口 */
@GetMapping("/calculateConc/caclAndSave")
boolean calculateConc();
/* AlarmAnalysisNuclideParamController下相关接口 */
@GetMapping("/nuclideParam/refresh")
boolean refreshParam();
/* SysDatabaseController下相关接口 */
@GetMapping("/sysDatabase/getNameById")
String getDatabaseName(@RequestParam String id);

View File

@ -1,36 +0,0 @@
package org.jeecg.modules.quartz.job;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.config.mqtoken.UserTokenContext;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.feignclient.AbnormalAlarmClient;
import org.quartz.*;
/**
* 此处的同步是指:当定时任务的执行时间大于任务的时间
* 间隔时会等待第一个任务执行完成才会走第二个任务
*/
/**
* 定时更新核素浓度计算参数
*/
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class NuclideParamJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
UserTokenContext.setToken(TokenUtils.getTempToken());
AbnormalAlarmClient alarmClient = SpringContextUtils.getBean(AbnormalAlarmClient.class);
alarmClient.refreshParam();
}catch (Exception e){
log.error("定时任务[NuclideParamJob]执行异常: {}", e.getMessage());
}finally {
UserTokenContext.remove();
}
}
}

View File

@ -1,48 +0,0 @@
package org.jeecg.modules.quartz.job;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.config.mqtoken.UserTokenContext;
import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.feignclient.AbnormalAlarmClient;
import org.quartz.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 此处的同步是指:当定时任务的执行时间大于任务的时间
* 间隔时会等待第一个任务执行完成才会走第二个任务
*/
/**
* 定时计算核素浓度均值
*/
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class NucliedAvgJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
UserTokenContext.setToken(TokenUtils.getTempToken());
AbnormalAlarmClient alarmClient = SpringContextUtils.getBean(AbnormalAlarmClient.class);
alarmClient.calculateConc();
log.info(log());
}catch (Exception e){
log.error("定时任务[NucliedAvgJob]执行异常: {}", e.getMessage());
}finally {
UserTokenContext.remove();
}
}
private String log(){
String now = LocalDateTime.now()
.format(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME));
return "计算核素浓度均值的定时任务成功执行, " +
"任务执行类: org.jeecg.modules.quartz.job.NucliedAvgJob, " +
"任务执行时间: " + now;
}
}

View File

@ -0,0 +1,156 @@
package org.jeecg.modules.quartz.jobs;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.constant.RedisConstant;
import org.jeecg.common.util.DataTool;
import org.jeecg.common.util.NumUtil;
import org.jeecg.common.util.TemplateUtil;
import org.jeecg.modules.base.entity.Rule;
import org.jeecg.modules.base.entity.monitor.ItemHistory;
import org.jeecg.modules.base.entity.postgre.AlarmLog;
import org.jeecg.modules.base.entity.postgre.AlarmRule;
import org.jeecg.modules.feignclient.ManageUtil;
import org.jeecg.modules.quartz.entity.Monitor;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.jeecg.modules.base.enums.SourceType.DATABASE;
import static org.jeecg.modules.base.enums.Template.MONITOR_DATABASE;
@Slf4j
@Component
public class DatabaseJob extends Monitor {
/**
* 解析Database预警规则
**/
@Scheduled(cron = "${task.period:0 0/1 * * * ?}")
public void execute(){
init();
// 查询所有Database的报警规则,根据报警规则查询监控项数据
String pattern = RedisConstant.PREFIX_RULE + DATABASE.getType();
Set<String> keys = getRedisStreamUtil().keys(pattern);
if (CollUtil.isEmpty(keys)) return;
// 时间间隔为每分钟
LocalDateTime now = LocalDateTime.now()
.withSecond(0)
.withNano(0);
LocalDateTime beforeMin = now.minusMinutes(1);
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern(DateConstant.DATE_TIME);
String start = beforeMin.format(formatter);
String end = now.format(formatter);
String prefixSilence = RedisConstant.PREFIX_SILENCE;
String operator = null;
for (String ruleKey : keys) {
try {
AlarmRule alarmRule = (AlarmRule) getRedisStreamUtil().get(ruleKey);
// 如果报警规则为空,或者在沉默周期内,跳过当前规则
operator = alarmRule.getOperator();
String ruleId = alarmRule.getId();
String itemId = alarmRule.getItemId();
String type = alarmRule.getItemType();
Integer itemType = StrUtil.isBlank(type) ? 0 : Integer.parseInt(type);
String silenceKey = prefixSilence + ruleId;
boolean hasKey = getRedisStreamUtil().hasKey(silenceKey);
boolean blank1 = StrUtil.isBlank(operator);
boolean blank2 = StrUtil.isBlank(itemId);
if (blank1 || blank2 || hasKey) continue;
// 根据sourceId查询Database信息(缓存)
String sourceId = alarmRule.getSourceId();
String databaseName = getAlarmClient().getDatabaseName(sourceId);
/*// 根据监控项id选择要查询的监控项信息
Item item = Item.of(itemId);
if (ObjectUtil.isNull(item)) continue;
Number current = null;
switch (item){
case DATABASE_CONN: // 监控项-2: 测试数据源是否可以连接成功
current = isConnection(sourceId);
break;
// 追加的监控项...
default:
break;
}*/
// 向运管查询监控项数据
String token = ManageUtil.getToken();
Result<ItemHistory> result = getMonitorSystem().itemBack(itemId, itemType, start, end, token);
ItemHistory itemHistory = result.getResult();
if (ObjectUtil.isNull(itemHistory)){
log.warn("Database监控异常: [{}]查询监控项历史数据为空", databaseName);
continue;
}
Double current = itemHistory.getNow();
// 解析预警规则,判断是否需要报警
ObjectMapper mapper = new ObjectMapper();
Rule rule = mapper.readValue(operator, Rule.class);
String op = rule.getOperator();
Double threshold = rule.getThreshold();
boolean needWarn = NumUtil.compare(current, threshold, op);
if (needWarn){
// 记录报警日志
AlarmLog alarmLog = new AlarmLog();
alarmLog.setRuleId(ruleId);
alarmLog.setOperator(operator);
alarmLog.setAlarmValue(StrUtil.toString(current));
String ruleName = alarmRule.getName();
Map<String, Object> data = DataTool.getInstance().
put(databaseName).put(ruleName).put(rule.joint()).put(current).get();
MessageDTO messageDTO = TemplateUtil.parse(MONITOR_DATABASE.getCode(), data);
alarmLog.setAlarmInfo(messageDTO.getContent());
getAlarmClient().create(alarmLog);
// 规则触发报警后,设置该规则的沉默周期(如果有)
// 沉默周期失效之前,该规则不会再次被触发
Long silenceCycle = alarmRule.getSilenceCycle();
ruleSilence(silenceKey, silenceCycle);
// 发送报警信息
String groupId = alarmRule.getContactId();
String notific = alarmRule.getNotification();
getSendMessage().send(messageDTO, groupId, notific);
getPushAppUtil().pushToSingle(messageDTO, groupId);
}
} catch (JsonProcessingException e) {
log.error("Database预警规则: {}解析失败,失败原因: {}", operator, e.getMessage());
}catch (Exception e){
log.error("Database监控异常: {}", e.getMessage());
}
}
destroy();
}
/*
* 监控项-2: 测试数据源是否可以连接成功 (0:失败 1:成功)
* */
/*private Integer isConnection(String databaseId){
int res = 1;
String statusKey = RedisConstant.DATABASE_STATUS;
NameValue nameValue = (NameValue)getRedisUtil().hget(statusKey, databaseId);
if (ObjectUtil.isNull(nameValue) || ObjectUtil.isNull(nameValue.getValue()) || !nameValue.getValue())
res = 0;
return res;
}*/
}

View File

@ -0,0 +1,130 @@
package org.jeecg.modules.quartz.jobs;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.constant.RedisConstant;
import org.jeecg.common.util.DataTool;
import org.jeecg.common.util.NumUtil;
import org.jeecg.common.util.TemplateUtil;
import org.jeecg.modules.base.dto.NameValue;
import org.jeecg.modules.base.entity.Rule;
import org.jeecg.modules.base.entity.postgre.AlarmLog;
import org.jeecg.modules.base.entity.postgre.AlarmRule;
import org.jeecg.modules.base.enums.Item;
import org.jeecg.modules.quartz.entity.Monitor;
import org.quartz.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.jeecg.modules.base.enums.SourceType.EMAIL;
import static org.jeecg.modules.base.enums.Template.MONITOR_EMAIL;
@Slf4j
@Component
public class EmailJob extends Monitor{
/**
* 解析Email预警规则
**/
@Scheduled(cron = "${task.period:0 0/1 * * * ?}")
public void execute(){
init();
// 查询所有Email的报警规则,根据报警规则查询监控项数据
String pattern = RedisConstant.PREFIX_RULE + EMAIL.getType();
Set<String> keys = getRedisStreamUtil().keys(pattern);
if (CollUtil.isEmpty(keys)) return;
String prefixSilence = RedisConstant.PREFIX_SILENCE;
String operator = null;
for (String ruleKey : keys) {
try {
AlarmRule alarmRule = (AlarmRule) getRedisStreamUtil().get(ruleKey);
// 如果报警规则为空,或者在沉默周期内,跳过当前规则
operator = alarmRule.getOperator();
String ruleId = alarmRule.getId();
String itemId = alarmRule.getItemId();
String silenceKey = prefixSilence + ruleId;
boolean hasKey = getRedisStreamUtil().hasKey(silenceKey);
boolean blank1 = StrUtil.isBlank(operator);
boolean blank2 = StrUtil.isBlank(itemId);
if (blank1 || blank2 || hasKey) continue;
// 根据sourceId查询Eamil信息(缓存)
String sourceId = alarmRule.getSourceId();
String emailName = getAlarmClient().getEmailName(sourceId);
// 根据监控项id选择要查询的监控项信息
Item item = Item.of(itemId);
if (ObjectUtil.isNull(item)) continue;
Number current = null;
switch (item){
case EMAIL_CONN: // 监控项-1: 测试邮箱服务是否可以连接成功
current = isConnection(sourceId);
break;
// 追加的监控项...
default:
break;
}
// 解析预警规则,判断是否需要报警
ObjectMapper mapper = new ObjectMapper();
Rule rule = mapper.readValue(operator, Rule.class);
String op = rule.getOperator();
Double threshold = rule.getThreshold();
boolean needWarn = NumUtil.compare(current, threshold, op);
if (needWarn){
// 记录报警日志
AlarmLog alarmLog = new AlarmLog();
alarmLog.setRuleId(ruleId);
alarmLog.setOperator(operator);
alarmLog.setAlarmValue(StrUtil.toString(current));
String ruleName = alarmRule.getName();
Map<String, Object> data = DataTool.getInstance().
put(emailName).put(ruleName).put(rule.joint()).put(current).get();
MessageDTO messageDTO = TemplateUtil.parse(MONITOR_EMAIL.getCode(), data);
alarmLog.setAlarmInfo(messageDTO.getContent());
getAlarmClient().create(alarmLog);
// 规则触发报警后,设置该规则的沉默周期(如果有)
// 沉默周期失效之前,该规则不会再次被触发
Long silenceCycle = alarmRule.getSilenceCycle();
ruleSilence(silenceKey, silenceCycle);
// 发送报警信息
String groupId = alarmRule.getContactId();
String notific = alarmRule.getNotification();
getSendMessage().send(messageDTO, groupId, notific);
getPushAppUtil().pushToSingle(messageDTO, groupId);
}
} catch (JsonProcessingException e) {
log.error("Email预警规则: {}解析失败,失败原因: {}", operator, e.getMessage());
}catch (Exception e){
log.error("Email监控异常: {}", e.getMessage());
}
}
destroy();
}
/*
* 监控项-1: 测试邮箱服务是否可以连接成功 (0:失败 1:成功)
* */
private Integer isConnection(String emailId){
int res = 1;
String statusKey = RedisConstant.EMAIL_STATUS;
NameValue nameValue = (NameValue)getRedisUtil().hget(statusKey, emailId);
if (ObjectUtil.isNull(nameValue) || ObjectUtil.isNull(nameValue.getValue()) || !nameValue.getValue())
res = 0;
return res;
}
}

View File

@ -0,0 +1,137 @@
package org.jeecg.modules.quartz.jobs;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.FeignException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.DateConstant;
import org.jeecg.common.constant.RedisConstant;
import org.jeecg.common.util.DataTool;
import org.jeecg.common.util.NumUtil;
import org.jeecg.common.util.TemplateUtil;
import org.jeecg.modules.base.entity.Rule;
import org.jeecg.modules.base.entity.monitor.ItemHistory;
import org.jeecg.modules.base.entity.postgre.AlarmLog;
import org.jeecg.modules.base.entity.postgre.AlarmRule;
import org.jeecg.modules.feignclient.ManageUtil;
import org.jeecg.modules.quartz.entity.Monitor;
import org.quartz.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Set;
import static org.jeecg.modules.base.enums.SourceType.SERVER;
import static org.jeecg.modules.base.enums.Template.MONITOR_SERVER;
@Slf4j
@Component
public class ServerJob extends Monitor{
/**
* 根据host定时查询服务器信息
* 并向消息队列中推送信息
*
*/
@Scheduled(cron = "${task.period:0 0/1 * * * ?}")
public void execute(){
init();
// 查询所有Server的报警规则,根据报警规则查询监控项数据
String pattern = RedisConstant.PREFIX_RULE + SERVER.getType();
Set<String> keys = getRedisStreamUtil().keys(pattern);
if (CollUtil.isEmpty(keys)) return;
// 时间间隔为每分钟
LocalDateTime now = LocalDateTime.now()
.withSecond(0)
.withNano(0);
LocalDateTime beforeMin = now.minusMinutes(1);
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern(DateConstant.DATE_TIME);
String start = beforeMin.format(formatter);
String end = now.format(formatter);
String prefixSilence = RedisConstant.PREFIX_SILENCE;
String operator = null;
for (String ruleKey : keys) {
try {
AlarmRule alarmRule = (AlarmRule) getRedisStreamUtil().get(ruleKey);
// 如果报警规则为空,或者在沉默周期内,跳过当前规则
operator = alarmRule.getOperator();
String ruleId = alarmRule.getId();
String itemId = alarmRule.getItemId();
String type = alarmRule.getItemType();
Integer itemType = StrUtil.isBlank(type) ? 0 : Integer.parseInt(type);
String silenceKey = prefixSilence + ruleId;
boolean hasKey = getRedisStreamUtil().hasKey(silenceKey);
boolean blank1 = StrUtil.isBlank(operator);
boolean blank2 = StrUtil.isBlank(itemId);
if (blank1 || blank2 || hasKey) continue;
// 根据sourceId查询Server信息(缓存)
String sourceId = alarmRule.getSourceId();
String serverName = getAlarmClient().getServerName(sourceId);
// 向运管查询监控项数据
String token = ManageUtil.getToken();
Result<ItemHistory> result = getMonitorSystem().itemBack(itemId, itemType, start, end, token);
ItemHistory itemHistory = result.getResult();
if (ObjectUtil.isNull(itemHistory)){
log.warn("Server监控异常: [{}]查询监控项历史数据为空", serverName);
continue;
}
Double current = itemHistory.getNow();
// 解析预警规则,判断是否需要报警
ObjectMapper mapper = new ObjectMapper();
Rule rule = mapper.readValue(operator, Rule.class);
String op = rule.getOperator();
Double threshold = rule.getThreshold();
boolean needWarn = NumUtil.compare(current, threshold, op);
if (needWarn){
// 记录报警日志
AlarmLog alarmLog = new AlarmLog();
alarmLog.setRuleId(ruleId);
alarmLog.setOperator(operator);
alarmLog.setAlarmValue(StrUtil.toString(current));
String ruleName = alarmRule.getName();
Map<String, Object> data = DataTool.getInstance().
put(serverName).put(ruleName).put(rule.joint()).put(current).get();
MessageDTO messageDTO = TemplateUtil.parse(MONITOR_SERVER.getCode(), data);
alarmLog.setAlarmInfo(messageDTO.getContent());
getAlarmClient().create(alarmLog);
// 规则触发报警后,设置该规则的沉默周期(如果有)
// 沉默周期失效之前,该规则不会再次被触发
Long silenceCycle = alarmRule.getSilenceCycle();
ruleSilence(silenceKey, silenceCycle);
// 发送报警信息
String groupId = alarmRule.getContactId();
String notific = alarmRule.getNotification();
getSendMessage().send(messageDTO, groupId, notific);
getPushAppUtil().pushToSingle(messageDTO, groupId);
}
}catch (FeignException.Unauthorized e){
ManageUtil.refreshToken();
log.warn("向运管系统查询ItemHistory信息异常: Token失效,已刷新Token");
} catch (JsonProcessingException e) {
log.error("Server预警规则: {}解析失败,失败原因: {}", operator, e.getMessage());
}catch (Exception e){
log.error("Server监控异常: {}", e.getMessage());
}
}
destroy();
}
}