
前面两篇分别说了报警执行器和报警规则的定义及用户扩展加载,接下来就是比较核心的一块了,如何将报警规则和报警执行器关联起来,即当发生报警时,应该call哪一个报警执行器
在正式进入之前,有必要额外声明一下,因为目前的v1版本,没有开放报警规则的自定义,也就是说,目前只支持默认的报警规则,所以接下来的主要内容将集中在
如果对于报警规则,依然不是很清晰的,可以阅读一下《报警系统QuickAlarm之报警规则的设定与加载》
这里简单的进行说明,系统中默认的报警规则结构为:
通过前面的报警规则的简单说明,基本上也可以捞出报警规则的解析原则了
上面是一个简单的解析规则,当然实际上和这个差不多,但有一些问题需要额外注意
再次将报警规则类拿出来看一下
/**
* 报警用户
*/
private List<String> users;
/**
* 报警的阀值
*/
private List<AlarmThreshold> alarmThreshold;
/**
* 最小的报警数
*/
private int minLimit;
/**
* 最大的报警数
*/
private int maxLimit;
/**
* 报警类型 {@link IExecute#getName()}
*/
private String alarmLevel;
/**
* true 表示当报警超过当前的阀值之后, 将提升报警的程度
*/
private boolean autoIncEmergency;针对上面的问题,逐一说明
autoIncEmergency 这个参数,如果为true,则表示可以走上面的哪个区间映射的规则;否则就全部走AlarmConfig中默认的报警类型了autoIncEmergency=true时,才有小,也就是我们前面说的不同的报警执行器,根据阀值区间进行排序,开启之后,遍历,判断频率是否在这个区间内,若在,则表示可以选择它了基本上前面已经将整个逻辑都说了,所以实际的编码反而比较清晰了
/**
* 获取具体的报警执行器
* <p>
* 1. 未开启严重等级上升时, 直接返回
* 2. 开启之后, 判断当前的计数 范围
*
* @param alarmConfig 报警配置项, 内部所有的参数都不可能为null
*/
public static ExecuteHelper getExecute(final AlarmConfig alarmConfig,
int count) {
// 未达到报警的下限 or 超过报警的上限时
if (count < alarmConfig.getMinLimit() || count > alarmConfig.getMaxLimit()) {
return new ExecuteHelper(SimpleExecuteFactory.getExecute(NoneExecute.NAME),
alarmConfig.getUsers());
}
// 未开启报警升级, 直接返回
if (!alarmConfig.isAutoIncEmergency()) {
return new ExecuteHelper(SimpleExecuteFactory.
getExecute(alarmConfig.getAlarmLevel()),
alarmConfig.getUsers());
}
// 报警等级开启上升之趋势
// 1. 获取设置的默认等级
// 2. 判断当前的报警次数, 选择对应的报警类型
// 3. 选择具体的报警类型
String defaultLevel = alarmConfig.getAlarmLevel();
String selectLevel = null;
List<String> selectUser = alarmConfig.getUsers();
List<AlarmThreshold> list = alarmConfig.getAlarmThreshold();
boolean useNew = false;
boolean containDefaultLevel = false;
for (AlarmThreshold alarmThreshold : list) {
if (Objects.equals(alarmThreshold.getAlarmLevel(), defaultLevel)) {
containDefaultLevel = true;
}
}
for (AlarmThreshold alarmThreshold : list) {
// 表示当前的报警等级已经赶上默认的报警等级了, 所以要选择新的报警类型
if (Objects.equals(alarmThreshold.getAlarmLevel(), defaultLevel)) {
useNew = true;
}
if (count < alarmThreshold.getThreshold()) {
break;
}
selectLevel = alarmThreshold.getAlarmLevel();
// 选择新的报警类型时, 需要更新报警用户
selectUser = alarmThreshold.getUsers();
}
// 阀值列表中不包含默认报警类型,则根据新的来
if (!containDefaultLevel && selectLevel != null) {
return new ExecuteHelper(SimpleExecuteFactory.getExecute(selectLevel), selectUser);
}
// 如果阀值列表中包含了默认报警类型, 且已经超过默认阀值
if (useNew && selectLevel != null) {
return new ExecuteHelper(SimpleExecuteFactory.getExecute(selectLevel), selectUser);
} else {
return new ExecuteHelper(SimpleExecuteFactory.getExecute(defaultLevel), alarmConfig.getUsers());
}
}具体的实现基本和我们前面分析的一样,但有一个地方需要额外注意
AlarmThreshold中不包含默认报警方式时,优先选择阀值区间的报警方式AlarmThreshold中包含默认报警方式时,根据新的规则做处理(吐槽:上面这个实现有点绕,后面想办法规避下,搞得不太好理解了)
另外一个问题就是,上面的实现没有支持可以同时选择多个报警执行器的情况
因为考虑到后面肯定会对报警规则的定义和解析放开,所以先实现了一个简单的场景,具体的放在后面处理
到这里报警规则和报警执行器之间的解析关系已确定,剩下的东西就简单了,一个维持报警频率计数,一个报警线程池,再加上一个对外接口的封装而言
基本上,到这里主要的核心逻辑已经完成,小结一下本系统中的核心设计理念 -- 一切可自定义(当然目前差得有点远)