Order 实体类
package com.daidai.source.mocksource.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private String id;
private Integer userId;
private Integer money;
private Long createTime;
}
需求
就是每隔5秒统计最近5秒的每个用户的订单总数、订单的最大金额、订单的最小金额
主程序
package com.daidai.table;
import com.daidai.source.mocksource.domain.Order;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;
import java.time.Duration;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import static org.apache.flink.table.api.Expressions.$;
public class RealtimeOrderStatistics {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
DataStreamSource<Order> source = env.addSource(new SourceFunction<Order>() {
private Boolean isRunning = true;
@Override
public void run(SourceContext<Order> ctx) throws Exception {
while (isRunning) {
Random random = new Random();
Order order = new Order(
UUID.randomUUID().toString(),
random.nextInt(3),
random.nextInt(100),
System.currentTimeMillis()
);
TimeUnit.SECONDS.sleep(1);
ctx.collect(order);
}
}
@Override
public void cancel() {
isRunning = false;
}
});
SingleOutputStreamOperator<Order> watermarks = source
.assignTimestampsAndWatermarks(WatermarkStrategy.<Order>forBoundedOutOfOrderness(Duration.ofSeconds(2))
.withTimestampAssigner((event, timestamp) -> event.getCreateTime()));
tableEnv.createTemporaryView("t_order", watermarks, $("id"), $("userId"), $("money"), $("createTime").rowtime());
String sql = "select " +
"userId," +
"count(money) as totalCount," +
"max(money) as maxMoney," +
"min(money) as minMoney " +
"from t_order " +
"group by userId," +
"tumble(createTime, interval '5' second)";
Table result = tableEnv.sqlQuery(sql);
DataStream<Tuple2<Boolean, Row>> orderResult = tableEnv.toRetractStream(result, Row.class);
orderResult.print();
env.execute();
}
}
注意事项
这种空格得千万注意,不然就得和我一样找大半天错误 ,如果你是用 Table 风格的话,应该不会有这种担忧。