Flink ProcessFunction API自定义事件处理
作用:可以访问时间戳、watermark 以及注册定时事件。还可以输出特定的一些事件,例如超时事件等。Process Function 用来构建事件驱动的应用以及实现自定义的业务逻辑(使用之前的window 函数和转换算子无法实现)。例如,Flink SQL 就是使用 Process Function 实现的。
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | object WindowTest { def main(args : Array[String]) : Unit = { val env = StreamExecutionEnvironment.getExecutionEnvironment env.setParallelism( 1 ) env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) val socketStream = env.socketTextStream( "hadoop102" , 7777 ) val dataStream : DataStream[SensorReading] = socketStream.map(d = > { val arr = d.split( "," ) SensorReading(arr( 0 ).trim, arr( 1 ).trim.toLong, arr( 2 ).toDouble) }) .assignTimestampsAndWatermarks( new BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds( 1 )) { override def extractTimestamp(t : SensorReading) : Long = t.timestamp * 1000 }) //自定义温度报警处理 val processStream = dataStream.keyBy( _ .id).process( new TempIncreAlert) //输出自定义业务逻辑 processStream.print( "process stream" ) //打印原始的dataStream dataStream.print( "data stream" ) env.execute( "window test" ) } } case class SensorReading(id : String, timestamp : Long, temperature : Double) //温度报警处理类 class TempIncreAlert extends KeyedProcessFunction[String, SensorReading, String] { //定义一个状态,保存上一条数据的温度 lazy val savedTemper : ValueState[Double] = getRuntimeContext.getState( new ValueStateDescriptor[Double]( "lastTemp" , classOf[Double])) //定义一个状态,保存定时器的时间戳 lazy val savedTimer : ValueState[Long] = getRuntimeContext.getState( new ValueStateDescriptor[Long]( "currentTimer" , classOf[Long])) override def processElement(i : SensorReading, context : KeyedProcessFunction[String, SensorReading, String] # Context, collector : Collector[String]) : Unit = { //取出上一个温度值 val preTemp = savedTemper.value() //更新温度值 savedTemper.update(i.temperature) //取出上一个定时器的时间戳 val preTimerTs = savedTimer.value() //如果温度在30度以上上升,则注册定时器 if (i.temperature > preTemp && preTemp > 30 && preTimerTs == 0 ) { //注册3秒后触发的定时器 val ts = context.timerService().currentProcessingTime() context.timerService().registerProcessingTimeTimer(ts + 3000 ) //保存刚注册的定时器时间戳 savedTimer.update(ts) } else if (i.temperature < preTemp || preTemp == 0 ) { //删除定时器 context.timerService().deleteProcessingTimeTimer(preTimerTs) //清空状态 savedTimer.clear() } } //定时器回调函数 override def onTimer(timestamp : Long, ctx : KeyedProcessFunction[String, SensorReading, String] # OnTimerContext, out : Collector[String]) : Unit = { //输出报警信息 out.collect(ctx.getCurrentKey + "温度超过30度且连续上升!" ) } } |
端口输入数据
[atguigu@hadoop102 ~]$ nc -lk 7777 sensor_1, 1547718200, 30 sensor_1, 1547718200, 29 sensor_1, 1547718200, 31 sensor_1, 1547718200, 33
控制台打印
data stream> SensorReading(sensor_1,1547718200,30.0) data stream> SensorReading(sensor_1,1547718200,29.0) data stream> SensorReading(sensor_1,1547718200,31.0) data stream> SensorReading(sensor_1,1547718200,33.0) process stream> sensor_1温度超过30度且连续上升!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 手把手教你更优雅的享受 DeepSeek
· 腾讯元宝接入 DeepSeek R1 模型,支持深度思考 + 联网搜索,好用不卡机!
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库