Flink不觸發窗口計算又不報錯的問題定位

剛接觸Flink不久,照着之前的一個老項目重構。好不容易寫完代碼並解決完各種報錯,結果發現即使不報錯也無法運出自己想要的效果。調試發現能正常消費到Kafka的消息,但是卻無法觸發窗口計算。在網上翻到一篇博客問題定位:Flink水位線不觸發問題 ,上面說是watermark有問題,通過Flink的管理控制檯發現watermark沒生成:
在這裏插入圖片描述
注意,截圖的時候我的問題已經解決了,沒有watermark的時候顯示的是no watermark,而不是上圖中的0

既然定位到是watermark的問題,就知道解決問題的方向了。通過對比重構前可以運行的舊代碼,發現了端倪。
舊代碼大致如下:
在這裏插入圖片描述
我重構後的錯誤代碼:
在這裏插入圖片描述

assignTimestampsAndWatermarks()方法返回的是一個全新的對象SingleOutputStreamOperator,而不再是原來那個DataStream,之所以第一種寫法可以,是因爲SingleOutputStreamOperator是DataStream的子類,看起來引用類型沒發生變化,但實際上返回的對象已經發生了改變。後面要用assignTimestampsAndWatermarks()方法返回的對象來創建一個臨時視圖而不是addSource()返回的那個:

DataStream<CallInfo> callInfoStream = environment
	.addSource(new FlinkKafkaConsumer<>(
    	config.getInputTopic(),
        new CallInfoSchema(), 
        kafkaConf))
    .assignTimestampsAndWatermarks(new AssignerWithPeriodicWatermarks<CallInfo>() {

		private static final long serialVersionUID = 1L;
			
		private long currentMaxTimestamp = 0;
	
		@Override
		public long extractTimestamp(CallInfo element, long previousElementTimestamp) {
			long timestamp = element.getEndTime();
	            
	        currentMaxTimestamp = Math.max(timestamp, currentMaxTimestamp);
	            
	        return timestamp;
		}
	
		@Override
		public Watermark getCurrentWatermark() {
			return new Watermark(currentMaxTimestamp);
		}
	}).setParallelism(1);
      
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(environment);
      
tableEnv.createTemporaryView(
	"CallInfo", 
    callInfoStream, 
    "traceType, traceId, elapsedTime, deviceId, callResult, streamId, streamType, "
    + "userId, groupId, childNum, recordType, startTime, endTime, dateStr, "
    + "successNum, failNum, rowtime.rowtime");

搞了半天,原來是我代碼寫錯了。這個問題坑就坑在它不會報錯,也沒有任何提示信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章