事件流匹配的另类方式

如果有一个实时数据需求:一个用户在指定时间内依次完成了事件A,B,C,D,那就给该用户推送消息。在不使用Flink Cep的情况下,有什么办法呢?

一个用户的行为数据流:"A","B","A","C","B","D","C","A","B","B","C","D",从这段事件流中,用户一共完成两次:ABCD。直接说下实现思路,为了演示方便,这是用系统时间代替事件时间,用户的历史状态保存在内存里,状态的保存方式"0_0_0_0"(ABCD四个事件,初始状态用0表示,后续逐渐替换成时间戳,具体细节看下图)

事件流匹配的另类方式_第1张图片

 具体代码如下

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Test {
    public static Map eventMap = new HashMap<>();
    public static void main(String[] args) throws Exception{
        eventMap.put("A",0);
        eventMap.put("B",1);
        eventMap.put("C",2);
        eventMap.put("D",3);

        String[] eventArr = new String[]{"A","B","A","C","B","D","C","A","B","B","C","D"};
        cl(eventArr);
    }


    public static String cl(String[] eventArr)throws Exception{
        String result = "0_0_0_0";//记录事件流(ABC)匹配结果
        for (String event : eventArr) {
            String[] events = result.split("_");
            Integer eventIndex = eventMap.get(event);
            String lastEventTime = "";
            if(eventIndex==0){
                //使用系统当前时间当作时间流开始的时间
                events[eventIndex] = System.currentTimeMillis()+"";
            }else{
                lastEventTime = events[eventIndex - 1];
            }

            result = String.join("_",events);
            //如果是最后一个事件C,判断是否有前置事件B,如果有的话说明事件流匹配成功
            if(eventIndex == events.length - 1 ){
                if(!"0".equals(lastEventTime)){
                    long endTime = System.currentTimeMillis();
                    System.out.println("事件流匹配成功!!,事件流开始时间:"+events[eventIndex - 1]+
                            ",事件流结束时间:"+endTime+",时间流耗时:"+(endTime-Long.parseLong(events[eventIndex - 1]))+"ms");
                    events[eventIndex - 1] = "0";
                    result = String.join("_",events);
                }
            }

            if(!"0".equals(lastEventTime)){
                if(eventIndex>0){
                    events[eventIndex] = events[eventIndex-1];
                    events[eventIndex - 1] = "0";
                    result = String.join("_",events);
                }
            }

            Thread.sleep(new Random().nextInt(300));
        }
        return result;
    }
}

输出

事件流匹配成功!!,事件流开始时间:1660043229079,事件流结束时间:1660043229885,
时间流耗时:806ms

事件流匹配成功!!,事件流开始时间:1660043230402,事件流结束时间:1660043231100,
时间流耗时:698ms

你可能感兴趣的:(flink,事件流,匹配,flink,cep,flink)