20-11-flink项目

这篇博客介绍了如何使用Flink的CoProcessFunction处理实时对账场景,通过事件时间窗口进行订单和支付事件的匹配。当订单和支付事件匹配成功时,直接输出;若未匹配,设置定时器并在超时时将未匹配的事件输出到特定侧输出流。
摘要由CSDN通过智能技术生成

实时对账的数据,这里面就不仅有订单的数据了,还会有支付的数据。

不能用union因为数据结构是不一样的。

先得到connectedStreams再keyBy

看下源码,这个是连接之后再去keyBy:

两条流,两个位置,第一个位置和第二个位置,都是key的位置。

---

我们看下coProcessFunction

代码:

// 自定义CoProcessFunction,实现两条流数据的匹配检验
class OrderPayTxDetect() extends CoProcessFunction[OrderEvent, ReceiptEvent, (OrderEvent, ReceiptEvent)]{
  // 用两个ValueState,保存当前交易对应的支付事件和到账事件
  lazy val payState: ValueState[OrderEvent] = getRuntimeContext.getState(new ValueStateDescriptor[OrderEvent]("pay", classOf[OrderEvent]))
  lazy val receiptState: ValueState[ReceiptEvent] = getRuntimeContext.getState(new ValueStateDescriptor[ReceiptEvent]("receipt", classOf[ReceiptEvent]))

  val unmatchedPays = new OutputTag[OrderEvent]("unmatched-pays")
  val unmatchedReceipts = new OutputTag[ReceiptEvent]("unmatched-receipts")

  override def processElement1(pay: OrderEvent, ctx: CoProcessFunction[OrderEvent, ReceiptEvent, (OrderEvent, ReceiptEvent)]#Context, out: Collector[(OrderEvent, ReceiptEvent)]): Unit = {
    // pay来了,考察有没有对应的receipt来过
    val receipt = receiptState.value()
    if( receipt != null ){
      // 如果已经有receipt,那么正常匹配,输出到主流
      out.collect( (pay, receipt) )
      receiptState.clear()
    } else{
      // 如果receipt还没来,那么把pay存入状态,注册一个定时器等待5秒
      payState.update(pay)
      ctx.timerService().registerEventTimeTimer( pay.eventTime * 1000L + 5000L )
    }
  }

  override def processElement2(receipt: ReceiptEvent, ctx: CoProcessFunction[OrderEvent, ReceiptEvent, (OrderEvent, ReceiptEvent)]#Context, out: Collector[(OrderEvent, ReceiptEvent)]): Unit = {
    // receipt来了,考察有没有对应的pay来过
    val pay = payState.value()
    if( pay != null ){
        // 如果已经有pay,那么正常匹配,输出到主流
        out.collect( (pay, receipt) )
        payState.clear()
    } else{
      // 如果pay还没来,那么把receipt存入状态,注册一个定时器等待3秒
      receiptState.update(receipt)
      ctx.timerService().registerEventTimeTimer( receipt.timestamp * 1000L + 3000L )
    }
  }

  // 定时器触发,有两种情况,所以要判断当前有没有pay和receipt
  override def onTimer(timestamp: Long, ctx: CoProcessFunction[OrderEvent, ReceiptEvent, (OrderEvent, ReceiptEvent)]#OnTimerContext, out: Collector[(OrderEvent, ReceiptEvent)]): Unit = {
    // 如果pay不为空,说明receipt没来,输出unmatchedPays
    if( payState.value() != null )
      ctx.output(unmatchedPays, payState.value())
    if( receiptState.value() != null )
      ctx.output(unmatchedReceipts, receiptState.value())
    // 清空状态
    payState.clear()
    receiptState.clear()
  }
}

coprocessFunction实现的是一国两制的。

---20---

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值