Flink -- 案例分析一

1、实时统计道路的拥堵的情况,判断标准是统计15分钟内的车流量和平均车速,每一分钟计算一次
public class Demo05Car {
    public static void main(String[] args) throws Exception{
        /**需求:实时的统计道路的拥堵的情况,使用有界数据流来模拟数据
         * 实现的方式可以通过统计15分钟内的车流量,每分钟计算一次
         * 判断是否拥堵的条件:
         *  计算一段时间内通过平均车速和车流量判断
         */
        //首先构建Flink的环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        //读取有界数据流:
        DataStream<String> lineDS = env.readTextFile("flink/data/cars_sample.txt");
        /**
         * 以为是每分钟计算的是15分钟车流量,所以根据需求选择滑动的事件时间窗口,所有需要指定事件时间和水位线
         */
        //对数据进行解析
        DataStream<Car> carDS = lineDS.map(kv -> {
            String[] split = kv.split(",");
            //从数据表可以知道数据表中有很多的元素,使用元组接受时会比较麻烦,所以可以创建一个类来分装这些数据。
            Car car = new Car(split[0], split[1], split[2], split[3], split[4], split[5], split[6], Long.parseLong(split[7]), Double.parseDouble(split[8]));
            return car;
        });

        //指定对应的事件事件和水位线
        SingleOutputStreamOperator<Car> assCarDS = carDS.assignTimestampsAndWatermarks(
                WatermarkStrategy
                        //指定水位线,默认最新的一条数据的时间戳
                        .<Car>forMonotonousTimestamps()
                        .withTimestampAssigner((car, ts) -> car.getTime())
        );

        //按照道路的编号进行分组
        KeyedStream<Car, String> carRoadIdDS = assCarDS.keyBy(kv -> kv.getRoadId());


        //划分窗口.使用的时滑动的事件时间窗口,指定窗口的大小和滑动的间隔
        WindowedStream<Car, String, TimeWindow> windowDS = carRoadIdDS
                .window(SlidingEventTimeWindows.of(Time.minutes(15), Time.minutes(1)));
        
        //统计车流量和平均速度
        /**
         * process方法每一个窗口执行一次,是作用在每一个窗口上面
         * @param key :分组的key(道路编号)
         * @param context :flink上下文对象。可以或flink执行的环境信息
         * @param cars : 同一个窗口内所有的车辆数据
         * @param out:用于将数据发送到下游
         */
        SingleOutputStreamOperator<Result> resultDS = windowDS.process(new ProcessWindowFunction<Car, Result, String, TimeWindow>() {
            @Override
            public void process(String key,
                                ProcessWindowFunction<Car, Result, String, TimeWindow>.Context context,
                                Iterable<Car> cars, //同一个窗口的所有的数据量
                                Collector<Result> out) throws Exception {
                long flow = 0;
                Double sumSpeed = 0.0;
                for (Car car : cars) {
                    flow++;
                    sumSpeed = sumSpeed + car.getSpeed();
                }
                double avgSpeed = sumSpeed / flow;
                //将数据发送到下游
                out.collect(new Result(key, flow, avgSpeed));
            }
        });
        resultDS.print();
        env.execute();
    }
}





//创建一个类负责接收处理好后的数据:
class Result {
    private String roadId;
    private Long flow;
    private Double avgSpeed;

    @Override
    public String toString() {
        return "Result{" +
                "roadId='" + roadId + '\'' +
                ", flow=" + flow +
                ", avgSpeed=" + avgSpeed +
                '}';
    }

    public String getRoadId() {
        return roadId;
    }

    public void setRoadId(String roadId) {
        this.roadId = roadId;
    }

    public Long getFlow() {
        return flow;
    }

    public void setFlow(Long flow) {
        this.flow = flow;
    }

    public Double getAvgSpeed() {
        return avgSpeed;
    }

    public void setAvgSpeed(Double avgSpeed) {
        this.avgSpeed = avgSpeed;
    }

    public Result(String roadId, Long flow, Double avgSpeed) {
        this.roadId = roadId;
        this.flow = flow;
        this.avgSpeed = avgSpeed;
    }
}


//创建一个Car类来封装后的数据
class  Car {
    private String cardId;//车牌号
    private String roadId;//道路编号
    private String cityId;//城市编号
    private String carId;//卡口编号
    private String comId;//摄像头编号
    private String fx;//方向
    private String countyId;//区县
    private Long time;//时间
    private Double speed;//速度


    public Car(String cardId, String roadId, String cityId, String carId, String comId, String fx, String countyId, Long time, Double speed) {
        this.cardId = cardId;
        this.roadId = roadId;
        this.cityId = cityId;
        this.carId = carId;
        this.comId = comId;
        this.fx = fx;
        this.countyId = countyId;
        this.time = time;
        this.speed = speed;
    }

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public String getRoadId() {
        return roadId;
    }

    public void setRoadId(String roadId) {
        this.roadId = roadId;
    }

    public String getCityId() {
        return cityId;
    }

    public void setCityId(String cityId) {
        this.cityId = cityId;
    }

    public String getCarId() {
        return carId;
    }

    public void setCarId(String carId) {
        this.carId = carId;
    }

    public String getComId() {
        return comId;
    }

    public void setComId(String comId) {
        this.comId = comId;
    }

    public String getFx() {
        return fx;
    }

    public void setFx(String fx) {
        this.fx = fx;
    }

    public String getCountyId() {
        return countyId;
    }

    public void setCountyId(String countyId) {
        this.countyId = countyId;
    }

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }

    public Double getSpeed() {
        return speed;
    }

    public void setSpeed(Double speed) {
        this.speed = speed;
    }

    @Override
    public String toString() {
        return "Car{" +
                "cardId='" + cardId + '\'' +
                ", roadId='" + roadId + '\'' +
                ", cityId='" + cityId + '\'' +
                ", carId='" + carId + '\'' +
                ", comId='" + comId + '\'' +
                ", fx='" + fx + '\'' +
                ", countyId='" + countyId + '\'' +
                ", time=" + time +
                ", speed=" + speed +
                '}';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值