大数据学习之Flink——10底层 ProcessFunctionAPI

ProcessFunction 是一个低层次的流处理操作,允许返回所有 Stream 的基础构建模块:

  1. 访问 Event 本身数据(比如:Event 的时间,Event 的当前 Key 等)
  2. 管理状态 State(仅在 Keyed Stream 中)
  3. 管理定时器 Timer(包括:注册定时器,删除定时器等)
  4. 总而言之,ProcessFunction 是 Flink 最底层的 API,也是功能最强大的。
案例:
  1. 问题
    监控每一个手机,如果在 5 秒内呼叫它的通话都是失败的,发出警告信息。

  2. 代码

    package com.hjf.function
    
    import com.hjf.dataSource.StationLog
    import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor}
    import org.apache.flink.streaming.api.functions.KeyedProcessFunction
    import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
    import org.apache.flink.util.Collector
    
    /**
     * @author Jiang锋时刻
     * @create 2020-07-11 16:52
     */
    object TestProcessFunctionAPI {
      def main(args: Array[String]): Unit = {
        val streamEnv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
        streamEnv.setParallelism(1)
        import org.apache.flink.streaming.api.scala._
        val stream: DataStream[String] = streamEnv.socketTextStream("node01", 8888)
        stream.map(one => {
          val arr: Array[String] = one.split(",")
          new StationLog(arr(0).trim, arr(1).trim, arr(2).trim, arr(3).trim, arr(4).trim.toLong, arr(5).trim.toLong)
        }).keyBy(_.callOut).process(new MonitorCallFail).print()
        streamEnv.execute()
      }
    
      // 控制逻辑
      class MonitorCallFail() extends KeyedProcessFunction[String, StationLog, String] {
        // 使用一个状态记录时间
        lazy val timeState: ValueState[Long] = 
        	getRuntimeContext.getState(new ValueStateDescriptor[Long]("time", classOf[Long]))
    
        override def processElement(value: StationLog, context: KeyedProcessFunction[String, StationLog, String]#Context,
                                    collector: Collector[String]): Unit = {
          // 从状态中获取时间
          var time: Long = timeState.value()
          // 表示第一次发现呼叫的手机号是失败的
          if(value.callType.equals("fail") && time == 0) {
            // 获取当前时间
            val nowTime: Long = context.timerService().currentProcessingTime()
            // 5s后触发
            val onTime: Long = nowTime + 5000L
            // 注册定时器
            context.timerService().registerProcessingTimeTimer(onTime)
          }
    
          // 呼叫成功, 取消定时器
          if(!value.callType.equals("fail") && time != 0) {
            context.timerService().deleteProcessingTimeTimer(time)
            timeState.clear()
          }
        }
    
        // 定时器时间到了, 执行定时器, 发出警告
        override def onTimer(timestamp: Long, ctx: KeyedProcessFunction[String, StationLog, String]#OnTimerContext, out: Collector[String]): Unit = {
          val warnStr: String = "触发时间: " + timestamp + ", 手机号" + ctx.getCurrentKey
          out.collect(warnStr)
          timeState.clear()
        }
      }
    }
    
    
  3. 运行结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值