1.为啥不使用cep呢,cep的超时时间设置不好配置化,无法满足扩展要求
2.超时怎么界定。A事件发生后,过了N时间,还没有收到B事件,算超时。
代码如下:
java
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;
@Slf4j
public class AsyncModelTimeoutHandler extends KeyedProcessFunction<String, JSONObject, JSONObject> {
private static final long serialVersionUID = -61608451659272532L;
private transient ValueState<Long> firstDataTime;
private transient ValueState<Long> secondDataTime;
private transient ValueState<String> eventType;
@Override
public void open(Configuration parameters) throws Exception {
ValueStateDescriptor<Long> firstDataDescriptor = new ValueStateDescriptor<>("firstDataTime", Long.class);
firstDataTime = getRuntimeContext().getState(firstDataDescriptor);
ValueStateDescriptor<Long> secondDataDescriptor = new ValueStateDescriptor<>("secondDataTime", Long.class);
secondDataTime = getRuntimeContext().getState(secondDataDescriptor);
ValueStateDescriptor<String> eventTypeDescriptor = new ValueStateDescriptor<>("eventType", String.class);
eventType = getRuntimeContext().getState(eventTypeDescriptor);
}
@Override
public void processElement(JSONObject value, KeyedProcessFunction<String, JSONObject, JSONObject>.Context ctx, Collector<JSONObject> out) throws Exception {
Long currentTimestamp = value.getLong("ts");
if (value.containsKey("timeout")) {
//异步请求消息
long timeout = value.getLong("timeout");
firstDataTime.update(currentTimestamp + timeout);
eventType.update(value.getString("event"));
ctx.timerService().registerProcessingTimeTimer(currentTimestamp + timeout);
} else {
secondDataTime.update(currentTimestamp);
}
}
@Override
public void onTimer(long timestamp, KeyedProcessFunction<String, JSONObject, JSONObject>.OnTimerContext ctx, Collector<JSONObject> out) throws Exception {
Long firstTime = firstDataTime.value();
Long lastTime = secondDataTime.value();
if (lastTime == null || (firstTime != null && lastTime >= firstTime)) {
//超时了
log.info("AsyncModelTimeoutHandler onTimer handle triggerTime={}, firstTime={}, secondTime={},key={}", timestamp, firstTime, lastTime, ctx.getCurrentKey());
JSONObject r = new JSONObject();
r.put("id", ctx.getCurrentKey());
r.put("judgeTime", timestamp);
r.put("event", eventType.value());
out.collect(r);
}
firstDataTime.clear();
secondDataTime.clear();
eventType.clear();
}
}