规则引擎通常对我们的理解就是用来做模式匹配的,在数据流里面检测满足规则要求的数据。有人会问为什么需要规则动态变更呢?直接修改了规则把服务重启一下不就可以了吗,这个当然是不行的,规则引擎里面通常会维护很多不同的规则,例如在监控告警的场景下,如果每个人修改一下自己的监控阈值,就重启一下服务,必然会影响其他人的使用,因此需要线上满足规则动态变更加载。本篇基于Flink-Cep 来实现规则动态变更加载,同时参考了Flink中文社区刘博老师的分享(https://developer.aliyun.com/article/738454),在这个分享里面是针对在处理流中每一个Key使用不同的规则,本篇的讲解将不区分key的规则。
实现分析
•外部加载:通常规则引擎会有专门的规则管理模块,提供用户去创建自己的规则,对于Flink任务来说需要到外部去加载规则•动态更新:需要提供定时去检测规则是否变更•历史状态清理:在模式匹配中是一系列NFAState 的不断变更,如果规则发生变更那么这些State也就是无用的了,需要清理掉•易容的API: 不同的业务开发人员可能会有自己的规则管理、定时策略等,那么需要对外提供易用的API
实现步骤
用户API定义: InjectionPatternFunction 用于获取、定义用户的规则
package org.apache.flink.cep.functions;
import org.apache.flink.api.common.functions.Function;
import org.apache.flink.cep.pattern.Pattern;
import java.io.Serializable;
/**
* @param <T>
*/
public interface InjectionPatternFunction<T> extends Function, Serializable {
/**
* 你可能有一些初始化的工作
*/
public void init() throws Exception;
/**
* 获取新的pattern
* @return
*/
public Pattern<T,T> inject() throws Exception;
/**
* 一个扫描周期:ms
* @return
*/
public long getPeriod() throws Exception;
/**
* 规则是否发生变更
* @return
*/
public boolean isChanged() throws Exception;
}
那么如何将这个API暴露出去呢?正常情况的使用是:
CEP.pattern(dataStream,pattern)
希望以同样的方式暴露:
CEP.injectionPattern(dataStream,new YourInjectionPatternFunction)
就需要在CEP-Lib里面进行改造:
package or