Drools CEP 如何编写10分钟窗口内单IP访问应用超10次的触发规则
10分钟窗口内单IP访问超阈值的规则实现方案
现有规则的核心问题
你当前写的规则片段根本没指定统计维度,本质是把所有IP的访问事件混在一起算总数,就算计数到10触发了规则,你也不知道到底是哪个IP产生的访问,更别提动态跟踪每个IP的独立频次了。
核心实现思路
要实现单IP独立计数的需求,只要做两个最关键的调整:
- 把每一次访问应用的请求,都作为独立的事件对象丢给规则引擎,事件对象必须带两个字段:访问来源IP、访问发生时间
- 规则匹配的时候按IP做分组,给每个分组单独套10分钟的滑动时间窗口,单独算每个组的访问次数,根本不需要你自己手动维护所有IP的列表
可直接使用的规则代码(Drools 7+版本)
rule "Single IP access exceeds 10 times in 10m window" no-loop when // 按IP维度分组,绑定10分钟滑动时间窗口 $ipStat: Map(entryValue >= 10) from groupBy( // 对10分钟窗口内的所有访问事件做处理 AppAccessEvent() over window:time(10m), // 分组key:取访问事件的来源IP event -> event.getSourceIp(), // 聚合计算:统计对应IP在窗口内的事件总数 eventList -> eventList.size() ) then // 输出触发规则的IP和对应访问次数 $ipStat.forEach((ip, cnt) -> System.out.printf("触发规则:IP %s 10分钟内访问次数达%d,超过10次阈值%n", ip, cnt) ); end
实操踩坑提醒
- 真的不需要自己写Map存所有历史访问过的IP:规则的分组逻辑会自动把10分钟窗口里出现过的所有IP捞出来当分组key,每个key单独算访问量,不管是新出现的IP还是之前出现过的,都会自动被纳入统计,完全适配动态变化的IP集合
- 一定要开规则引擎的事件流模式:不然10分钟窗口的计算是按事件丢进引擎的时间算的,不是按访问实际发生的时间算的,很容易出现统计偏差
- 给访问事件类的时间字段加
@timestamp注解:明确告诉引擎时间窗口该按哪个字段算时间 no-loop属性一定不要删:不然规则触发的时候上下文更新会导致规则反复触发,刷一堆重复告警
内容的提问来源于stack exchange,提问作者Manjunath Pai
相关产品推荐
相关产品推荐

