package com.xicent.flink.cep;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.cep.CEP;
import org.apache.flink.cep.PatternSelectFunction;
import org.apache.flink.cep.PatternStream;
import org.apache.flink.cep.PatternTimeoutFunction;
import org.apache.flink.cep.functions.PatternProcessFunction;
import org.apache.flink.cep.functions.TimedOutPartialMatchHandler;
import org.apache.flink.cep.pattern.Pattern;
import org.apache.flink.cep.pattern.conditions.SimpleCondition;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;
import org.apache.flink.util.OutputTag;
import java.time.Duration;
import java.util.List;
import java.util.Map;
public class CepDemo {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
env.enableCheckpointing(1000);
//输入数据,提取事件时间
KeyedStream<LoginEvent, Integer> loginEventKeyedStream = env.fromElements(
new LoginEvent(1, "success", 1575600181000L),
new LoginEvent(2, "fail1", 1575600182000L),
new LoginEvent(2, "fail2", 1575600183000L),
new LoginEvent(3, "fail1", 1575600184000L),
new LoginEvent(3, "fail2", 1575600189000L)
).assignTimestampsAndWatermarks(
//注册watermark方法和旧版稍有不同
WatermarkStrategy.<LoginEvent>forBoundedOutOfOrderness(Duration.ofSeconds(0))
.withTimestampAssigner((event,timestamp)-> event.getEventTime()))
.keyBy(new KeySelector<LoginEvent, Integer>() {
@Override
public Integer getKey(LoginEvent loginEvent) throws Exception {
return loginEvent.getUserId();
}
});
//定义Pattern
Pattern<LoginEvent, LoginEvent> pattern = Pattern.<LoginEvent>begin("begin").where(new SimpleCondition<LoginEvent>() {
@Override
public boolean filter(LoginEvent loginEvent) throws Exception {
return "fail1".equals(loginEvent.getEventType());
}
}).<LoginEvent>next("next").where(new SimpleCondition<LoginEvent>() {
@Override
public boolean filter(LoginEvent loginEvent) throws Exception {
return "fail2".equals(loginEvent.getEventType());
}
}).within(Time.seconds(5));
//检测模式
PatternStream<LoginEvent> patternStream = CEP.pattern(loginEventKeyedStream, pattern);
//侧输出标志
OutputTag<LoginEvent> outputTag = new OutputTag<LoginEvent>("timeout") {};
//process方式提取数据
SingleOutputStreamOperator<Warning> process = patternStream.process(new MyPatternProcessFunction(outputTag));
process.print("process login failed twice");
//提取超时数据
process.getSideOutput(outputTag).print("process timeout");
//select方式提取数据
// SingleOutputStreamOperator<Warning> outputStreamOperator = patternStream
// .select(
// outputTag,
// new PatternTimeoutFunction<LoginEvent, LoginEvent>() {
// @Override
// public LoginEvent timeout(Map<String, List<LoginEvent>> map, long l) throws Exception {
//
// return map.get("begin").iterator().next();
// }
// },
// new PatternSelectFunction<LoginEvent, Warning>() {
// @Override
// public Warning select(Map<String, List<LoginEvent>> map) throws Exception {
// LoginEvent begin = map.get("begin").iterator().next();
// LoginEvent next = map.get("next").iterator().next();
//
// return new Warning(begin.getUserId(), begin.getEventTime(), next.getEventTime(), "Login failed twice");
// }
// });
//提取超时的数据
// DataStream<LoginEvent> timeoutDataStream = outputStreamOperator.getSideOutput(outputTag);
// timeoutDataStream.print("timeout");
//提取匹配数据
// outputStreamOperator.print("Login failed twice");
env.execute();
}
//TimedOutPartialMatchHandler提供了另外的processTimedOutMatch方法,这个方法对每个超时的部分匹配都会调用。
static class MyPatternProcessFunction extends PatternProcessFunction<LoginEvent, Warning> implements TimedOutPartialMatchHandler<LoginEvent> {
private OutputTag<LoginEvent> outputTag;
public MyPatternProcessFunction(OutputTag<LoginEvent> outputTag) {
this.outputTag = outputTag;
}
@Override
public void processMatch(Map<String, List<LoginEvent>> map, Context context, Collector<Warning> collector) throws Exception {
LoginEvent begin = map.get("begin").iterator().next();
LoginEvent next = map.get("next").iterator().next();
collector.collect(new Warning(begin.getUserId(), begin.getEventTime(), next.getEventTime(), "Login failed twice"));
}
@Override
public void processTimedOutMatch(Map<String, List<LoginEvent>> map, Context context) throws Exception {
context.output(outputTag,map.get("begin").iterator().next());
}
}
}
Flink超时数据提取
最新推荐文章于 2024-07-24 10:08:29 发布