可以使用 ProcessFunction 的 定时器实现
这里我们直接上代码
核心代码是,水位 + 10 分钟,然后注册定时器
在 OnTimer 方法里,时间到了的时候,就输出
package com.dsj361.flinksql
import java.sql.Timestamp
import java.util.Properties
import com.dsj361.common.enums.ModeEnum
import com.dsj361.common.lang.DateUtils
import com.dsj361.config.KafkaConfiguration
import org.apache.flink.formats.json.JsonNodeDeserializationSchema
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.node.ObjectNode
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.KeyedProcessFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer010
import org.apache.flink.table.api.scala._
import org.apache.flink.table.functions.ScalarFunction
import org.apache.flink.util.Collector
/**
*
*
* @author wangkai
* @date 2019/12/13 10:40
*/
object FlinkSqlWindowTest5 extends App {
class Utc2Local extends ScalarFunction {
def eval(timestamp: Timestamp): Timestamp = {
new Timestamp(timestamp.getTime + 28800000)
}
}
case class LogData(userName:String,ts:Long,age:Int)
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val tEnv = StreamTableEnvironment.create(env)
tEnv.registerFunction("Utc2Local", new Utc2Local)
val kafkaConf = KafkaConfiguration.getConfig(ModeEnum.DEV)
val prop: Properties = new Properties
prop.put("bootstrap.servers", "192.168.17.26:9092,192.168.17.27:9092,192.168.17.28:9092")
prop.put("group.id", "Flink_kafka_test_5")
prop.put("enable.auto.commit", "true")
prop.put("auto.commit.interval.ms", "100")
val consumer = new FlinkKafkaConsumer010[ObjectNode]("flink-test-05", new JsonNodeDeserializationSchema, prop)
class MyProcessFunction() extends KeyedProcessFunction[LogData,(LogData,Long),LogData] {
override def processElement(value: (LogData, Long), ctx: KeyedProcessFunction[LogData, (LogData, Long), LogData]#Context, out: Collector[LogData]): Unit = {
println("\n\n--------------process-------")
val watermark = value._1.ts + 60000L
ctx.timerService().registerEventTimeTimer(watermark)
}
override def onTimer(timestamp: Long, ctx: KeyedProcessFunction[LogData, (LogData, Long), LogData]#OnTimerContext, out: Collector[LogData]): Unit = {
println("\n\n--------------onTimer-----------")
out.collect(ctx.getCurrentKey)
}
}
val ds = env.addSource(consumer)
// 数据结构为:user_name:String, ts:TIMESTAMP
.map(f => {
(LogData (f.get("user_name").asText(), DateUtils.parseDateNewFormat(f.get("ts").asText()).getTime, f.get("age").asInt()),1L)
})
.assignAscendingTimestamps(f => f._1.ts)
.keyBy(_._1)
.process(new MyProcessFunction)
.print()
env.execute("job_name")
}