flink CEP示例
三分鐘時間內,出現三次及以上的溫度高於40度就算作是異常溫度,進行報警輸出
-
場景介紹
- 現在工廠當中有大量的感測裝置,用於檢測機器當中的各種指標資料,例如溫度,溼度,氣壓等,並實時上報資料到資料中心,現在需要檢測,某一個感測器上報的溫度資料是否發生異常。
-
異常的定義
- 三分鐘時間內,出現三次及以上的溫度高於40度就算作是異常溫度,進行報警輸出
- 測試資料
感測器裝置mac地址,檢測機器mac地址,溫度,溼度,氣壓,資料產生時間
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,38,0.52,1.1,2020-03-02 12:20:32
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,47,0.48,1.1,2020-03-02 12:20:35
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,50,0.48,1.1,2020-03-02 12:20:38
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,31,0.48,1.1,2020-03-02 12:20:39
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,52,0.48,1.1,2020-03-02 12:20:41
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,53,0.48,1.1,2020-03-02 12:20:43
00-34-5E-5F-89-A4,00-01-6C-06-A6-29,55,0.48,1.1,2020-03-02 12:20:45
程式碼
import java.util
import org.apache.commons.lang3.time.FastDateFormat
import org.apache.flink.cep.PatternSelectFunction
import org.apache.flink.cep.scala.pattern.Pattern
import org.apache.flink.cep.scala.{CEP, PatternStream}
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, StreamExecutionEnvironment}
import org.apache.flink.streaming.api.windowing.time.Time
//定義溫度資訊pojo
case class DeviceDetail(sensorMac:String,deviceMac:String,temperature:String,dampness:String,pressure:String,date:String)
//報警的裝置資訊樣例類
//感測器裝置mac地址,檢測機器mac地址,溫度
case class AlarmDevice(sensorMac:String,deviceMac:String,temperature:String)
/**
* 基於FlinkCEP的裝置溫度檢測
*/
object checkTemperature {
private val format: FastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss")
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
//指定時間型別
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.setParallelism(1)
import org.apache.flink.api.scala._
//接受資料
val socDS: DataStream[String] = env.socketTextStream("node01",9999)
val deviceDS: KeyedStream[DeviceDetail, String] = socDS.map(x => {
val stringArr: Array[String] = x.split(",")
DeviceDetail(stringArr(0), stringArr(1), stringArr(2), stringArr(3), stringArr(4), stringArr(5))
})
.assignAscendingTimestamps(x => {
format.parse(x.date).getTime
})
.keyBy(x => x.sensorMac)
//todo:定義Pattern,指定相關條件和模型序列
val pattern: Pattern[DeviceDetail, DeviceDetail] = Pattern.begin[DeviceDetail]("start")
.where(x => x.temperature.toInt >= 40)
.followedByAny("second")
.where(x => x.temperature.toInt >= 40)
.followedByAny("third")
.where(x => x.temperature.toInt >= 40)
.within(Time.minutes(3))
//todo:模式檢測,將模式應用到流中
val patternResult: PatternStream[DeviceDetail] = CEP.pattern(deviceDS,pattern)
//todo:選取結果
patternResult.select(new MyPatternResultFunction).print()
//todo: 啟動
env.execute("startTempeature")
}
}
//自定義PatternSelectFunction
class MyPatternResultFunction extends PatternSelectFunction[DeviceDetail,AlarmDevice]{
override def select(pattern: util.Map[String, util.List[DeviceDetail]]): AlarmDevice = {
val startDetails: util.List[DeviceDetail] = pattern.get("start")
val startResult: DeviceDetail = startDetails.iterator().next()
println("第一條資料: "+ startResult)
val secondDetails: util.List[DeviceDetail] = pattern.get("start")
val secondResult: DeviceDetail = secondDetails.iterator().next()
println("第二條資料: "+ secondResult)
val thirdDetails: util.List[DeviceDetail] = pattern.get("start")
val thirdResult: DeviceDetail = thirdDetails.iterator().next()
println("第三條資料: "+ thirdResult)
AlarmDevice(thirdResult.sensorMac,thirdResult.deviceMac,thirdResult.temperature)
}
}
- 輸入和輸出測試-1
左閉右開,收到第四條資料時,顯示滿足條件的三條資料 - 輸入和輸出測試-2
輸出如圖所示:共4條。
原因是由followedByAny
引起,詳情如下:
當第一個滿足條件的溫度52(此時有超過3條溫度>=40)出現後,在接受一條資料(左閉右開)顯示第一個紅框內容
當再接受一個溫度53時,由於非嚴格緊鄰定義,53在前面的3條大於40的溫度中任意選擇兩條,組合成滿足條件的:有3個大於40度的條件。此時按照組合公式:共C 3 2
共3種組合
建立訂單之後15分鐘之內一定要付款,否則就取消訂單
-
場景介紹
- 在我們的電商系統當中,經常會發現有些訂單下單之後沒有支付,就會有一個倒數計時的時間值,提示你在15分鐘之內完成支付,如果沒有完成支付,那麼該訂單就會被取消,主要是因為拍下訂單就會減庫存,但是如果一直沒有支付,那麼就會造成庫存沒有了,別人購買的時候買不到,然後別人一直不支付,就會產生有些人買不到,有些人買到了不付款,最後導致商家一件產品都賣不出去
-
需求
- 建立訂單之後15分鐘之內一定要付款,否則就取消訂單
-
訂單資料格式如下型別欄位說明
-
訂單編號
-
訂單狀態
- 1.建立訂單,等待支付
- 2.支付訂單完成
- 3.取消訂單,申請退款
- 4.已發貨
- 5.確認收貨,已經完成
-
訂單建立時間
-
訂單金額
-
20160728001511050311389390,1,2016-07-28 00:15:11,295
20160801000227050311955990,1,2016-07-28 00:16:12,165
20160728001511050311389390,2,2016-07-28 00:18:11,295
20160801000227050311955990,2,2016-07-28 00:18:12,165
20160728001511050311389390,3,2016-07-29 08:06:11,295
20160801000227050311955990,4,2016-07-29 12:21:12,165
20160804114043050311618457,1,2016-07-30 00:16:15,132
20160801000227050311955990,5,2016-07-30 18:13:24,165
程式碼
import java.util
import org.apache.commons.lang3.time.FastDateFormat
import org.apache.flink.cep.{PatternSelectFunction, PatternTimeoutFunction}
import org.apache.flink.cep.scala.{CEP, PatternStream, pattern}
import org.apache.flink.cep.scala.pattern.Pattern
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, OutputTag, StreamExecutionEnvironment}
import org.apache.flink.streaming.api.windowing.time.Time
/**
* 訂單下單未支付檢測
*/
case class OrderDetail(orderId:String,status:String,orderCreateTime:String,price :Double)
object orderCheck {
private val format: FastDateFormat = FastDateFormat.getInstance("yyy-MM-dd HH:mm:ss")
def main(args: Array[String]): Unit = {
val environment: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
environment.setParallelism(1)
import org.apache.flink.api.scala._
val sourceStream: DataStream[String] = environment.socketTextStream("node01",9999)
val keyedStream: KeyedStream[OrderDetail, String] = sourceStream.map(x => {
val strings: Array[String] = x.split(",")
OrderDetail(strings(0), strings(1), strings(2), strings(3).toDouble)
}).assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[OrderDetail](Time.seconds(5)) {
override def extractTimestamp(element: OrderDetail): Long = {
format.parse(element.orderCreateTime).getTime
}
}).keyBy(x=>x.orderId)
//定義pattern模式,指定條件
val pattern: Pattern[OrderDetail, OrderDetail] = Pattern.begin[OrderDetail]("start")
.where(order => order.status.equals("1"))
.followedBy("second")
.where(order => order.status.equals("2"))
.within(Time.minutes(15))
//呼叫select方法,提取事件序列,超時的事件要做報警提示
val orderTimeOutputTag = new OutputTag[OrderDetail]("orderTimeOut")
//將模式應用到流中
val patternStream: PatternStream[OrderDetail] = CEP.pattern(keyedStream,pattern)
//選擇結果
val selectedStream : DataStream[OrderDetail] = patternStream.select(orderTimeOutputTag, new OrderTimeOutPatternFunction,new OrderPatternFunction)
//列印測輸出流資料,過了15分支還沒支付的資料
selectedStream.getSideOutput(orderTimeOutputTag).print()
environment.execute()
}
}
//訂單超時檢查
class OrderTimeOutPatternFunction extends PatternTimeoutFunction[OrderDetail,OrderDetail]{
override def timeout(pattern: util.Map[String, util.List[OrderDetail]], timeoutTimestamp: Long): OrderDetail = {
val detail: OrderDetail = pattern.get("start").iterator().next()
println("超時訂單號為: "+ detail)
detail
}
}
class OrderPatternFunction extends PatternSelectFunction[OrderDetail,OrderDetail]{
override def select(pattern: util.Map[String, util.List[OrderDetail]]): OrderDetail = {
val detail: OrderDetail = pattern.get("second").iterator().next()
println("支付成功的訂單為: "+ detail)
detail
}
}
輸出
相關文章
- Flink - CEP(複雜事件處理)事件
- Flink CEP 在抖音電商的業務實踐
- 8.Flink實時專案之CEP計算訪客跳出
- Flink CEP 新特性進展與在實時風控場景的落地
- Flink1.7.2 DataStream Operator 示例AST
- Eta中的Apache Flink示例Apache
- Flink 原始碼解析--Stream、Job、ExecutionGraph的生成示例原始碼
- 【技術乾貨】程式碼示例:使用 Apache Flink 連線 TDengineApache
- 端智慧系列文章|端側如何實現實時CEP引擎
- [Flink/FlinkCDC] 實踐總結:Flink 1.12.6 升級 Flink 1.15.4
- 【Flink】Flink 底層RPC框架分析RPC框架
- [Flink] Flink 版本特性的演進
- flink實戰--讀寫Hive(Flink on Hive)Hive
- 【Flink】深入理解Flink-On-Yarn模式Yarn模式
- flink快速入門(部署+flink-sql)SQL
- Flink gelly
- Flink APIAPI
- Flink模式模式
- Flink - Watermark
- Flink SideOutPutLateEventCustomIDE
- Flink-Kafka-Connector Flink結合Kafka實戰Kafka
- Flink 1.16:Hive SQL 如何平遷到 Flink SQLHiveSQL
- FLINK CDC同步
- Flink漫談
- Flink簡介
- Flink 入門
- flink調優
- Flink Operations Playground #
- Flink實戰
- flink table apiAPI
- 【Flink入門修煉】2-2 Flink State 狀態
- [Flink/CDC/資料整合] 資料增量整合方案:Flink CDC
- 【Flink】基於 Flink 的流式資料實時去重
- Flink Forward k8s相關(1)--Flink部署方式ForwardK8S
- pod 示例
- 4.5.1.2.2 示例
- crontab 示例
- 聊聊flink的ParallelIteratorInputFormatParallelORM