目 录CONTENT

文章目录

2. [入门篇]零基础上手 Flink:开发第一个简单程序

冰点
2025-02-08 / 0 评论 / 0 点赞 / 16 阅读 / 9436 字

Apache Flink 是一个强大的流处理框架,广泛应用于实时数据分析和处理。本文将带你从零开始,

使用 Flink 开发一个简单的流处理程序,处理车辆定位物联网场景中的 GPS 信息。我们将从安装和配置环境开始,逐步构建并运行这个程序。

1. 环境准备,jdk+maven+idea 此步骤略

2. 创建 Maven 项目

目录结构如下

修改 pom.xml 文件,添加 Flink 依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>flink-st1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>1.14.2</version>
    </dependency>
    <!-- 如果是Maven项目,请确保pom.xml中有以下依赖 -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java_2.12</artifactId>
        <version>1.14.2</version> <!-- 确保版本与你的环境匹配 -->
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients_2.12</artifactId>
        <version>1.14.2</version> <!-- 确保版本与你的环境匹配 -->
    </dependency>
</dependencies>
</project>

3. 定义 GPS 数据结构

首先,我们需要定义一个类来表示 GPS 数据。创建一个名为 GpsData.java 的文件,内容如下

package org.example.vehiclegps;

public class GpsData {
    private String vehicleId;
    private double lat;
    private double lon;
    private long gpsTime;

    public GpsData(String vehicleId, double lat, double lon, long timestamp) {
        this.vehicleId = vehicleId;
        this.lat = lat;
        this.lon = lon;
        this.gpsTime = timestamp;
    }

    public String getVehicleId() {
        return vehicleId;
    }

    public double getLatitude() {
        return lat;
    }

    public double getLongitude() {
        return lon;
    }

    public long getTimestamp() {
        return gpsTime;
    }

    @Override
    public String toString() {
        return "GpsData{" +
                "vehicleId='" + vehicleId + '\'' +
                ", lat=" + lat +
                ", lon=" + lon +
                ", gpsTime=" + gpsTime +
                '}';
    }
}

4. 创建 Socket 服务器

接下来,创建一个 Socket 服务器,用于生成并发送模拟的 GPS 数据。创建一个名为 RandomGpsSocketServer.java 的文件

package org.example.vehiclegps;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;

public class FirstFlinkJob {

    public static void main(String[] args) throws Exception {
        // 设置执行环境
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 创建一个数据流,这里以socket文本流为例
        DataStream<String> text = env.socketTextStream("localhost", 9999);

        // 处理数据流
        DataStream<GpsData> gpsDataStream = text
                .flatMap(new GpsDataParser());

        // 打印结果至控制台
        gpsDataStream.print();

        // 开始执行
        env.execute("Vehicle GPS Data Processing");
    }

    // 实现FlatMapFunction接口,用来解析GPS数据
    public static final class GpsDataParser implements FlatMapFunction<String, GpsData> {

        @Override
        public void flatMap(String value, Collector<GpsData> out) {
            try {
                String[] parts = value.split(",");
                if (parts.length == 4) {
                    String vehicleId = parts[0].trim().replace("GpsData{vehicleId='", "").replace("'", "");
                    double latitude = Double.parseDouble(parts[1].trim().replace("lat=", "").replace(",", ""));
                    double longitude = Double.parseDouble(parts[2].trim().replace("lon=", "").replace(",", ""));
                    long timestamp = Long.parseLong(parts[3].trim().replace("gpsTime=", "").replace("}", ""));

                    out.collect(new GpsData(vehicleId, latitude, longitude, timestamp));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

现在,我们编写 Flink 作业来处理从 Socket 服务器接收到的 GPS 数据。FirstFlinkJob.java

package org.example.vehiclegps;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

public class RandomGpsSocketServer {

    private static final int PORT = 9999;
    private static final String[] VEHICLE_IDS = {"V1001", "V1002", "V1003", "V1004", "V1005"};

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("Socket服务器已启动,等待客户端连接...");

            try (Socket clientSocket = serverSocket.accept()) {
                System.out.println("客户端已连接");

                OutputStream outputStream = clientSocket.getOutputStream();
                PrintWriter out = new PrintWriter(outputStream, true);

                // 模拟持续发送随机生成的GPS数据
                Random random = new Random();
                while (true) {
                    GpsData gpsData = generateRandomGpsData(random);
                    out.println(gpsData.toString());
                    System.out.println("发送: " + gpsData.toString());
                    Thread.sleep(1000); // 每秒发送一次
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static GpsData generateRandomGpsData(Random random) {
        String vehicleId = VEHICLE_IDS[random.nextInt(VEHICLE_IDS.length)];
        double latitude = -90 + (180 * random.nextDouble());
        double longitude = -180 + (360 * random.nextDouble());
        long timestamp = System.currentTimeMillis();

        return new GpsData(vehicleId, latitude, longitude, timestamp);
    }
}

  1. 模拟车载设备上报定位数据

  2. flink 接收和处理结构

常见错误

  1. No ExecutorFactory found to execute the application. 一般为maven依赖配置的不对或者冲突

Exception in thread "main" java.lang.IllegalStateException: No ExecutorFactory found to execute the application.

at org.apache.flink.core.execution.DefaultExecutorServiceLoader.getExecutorFactory(DefaultExecutorServiceLoader.java:88)

at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.executeAsync(StreamExecutionEnvironment.java:2033)

at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.execute(StreamExecutionEnvironment.java:1931)

at org.apache.flink.streaming.api.environment.LocalStreamEnvironment.execute(LocalStreamEnvironment.java:69)

at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.execute(StreamExecutionEnvironment.java:1917)

at com.e6yun.epaas.admin.FirstFlinkProgram.main(FirstFlinkProgram.java:18)

使用上海交大的镜像库

https://mirror.sjtu.edu.cn/apache/flink/flink-1.18.1/

0

评论区