实时对账的数据,这里面就不仅有订单的数据了,还会有支付的数据。
不能用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---