环境准备与项目搭建:Flink开发环境配置、Maven/Gradle项目初始化、依赖引入
说实话,做流式元数据同步这个方向,环境搭不好后面全是坑。我见过太多同学在集群上跑任务报错,最后发现是本地环境和线上环境差了半个版本。这一章咱们就把地基打牢。
2.1 开发环境全景图
先看一张整体结构图,你心里就有数了:
这张图说白了就是咱们这章要干的事:从 IDE 到构建工具,再到依赖管理和运行环境,一层层搭起来。
2.2 JDK 与 IDE 配置
我个人习惯用 JDK 8 或 JDK 11。Flink 1.13 之后对 JDK 11 支持得不错,但如果你还在维护老项目,JDK 8 更稳妥。
IDE 我推荐 IntelliJ IDEA,社区版就够用。装好之后记得装这几个插件:
- Lombok — 省掉 getter/setter 的样板代码
- Maven Helper — 分析依赖冲突的神器
- Rainbow Brackets — 写 Flink 的链式调用时,括号层级一目了然
2.3 Maven 项目初始化
我建议用 Maven 做构建工具。为什么?因为 Flink 官方生态里 Maven 的 archetype 最成熟,社区里大部分示例也都是 Maven 项目。
创建一个空项目,然后手动配置 pom.xml。别用 archetype 生成,那个版本经常落后。
<?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>com.yourcompany</groupId>
<artifactId>flink-meta-sync</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<flink.version>1.14.4</flink.version>
<java.version>1.8</java.version>
<scala.binary.version>2.12</scala.binary.version>
</properties>
<dependencies>
<!-- Flink 核心 -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
scope 设为 provided。这样本地编译时能引用 Flink 的类,但打包时不会把 Flink 的 jar 打进去。线上集群自带 Flink 环境,你打进去反而会冲突。
2.4 核心依赖引入
元数据同步离不开连接外部系统。下面这张表是我整理的最常用依赖:
| 依赖用途 | Maven 坐标 | 版本建议 |
|---|---|---|
| JDBC 连接器 | flink-connector-jdbc_2.12 | 1.14.4 |
| MySQL 驱动 | mysql-connector-java | 8.0.28 |
| Kafka 连接器 | flink-connector-kafka_2.12 | 1.14.4 |
| Hive 集成 | flink-sql-connector-hive-2.3.6_2.12 | 1.14.4 |
| JSON 解析 | flink-json | 1.14.4 |
| 日志框架 | log4j-core / logback-classic | 2.17.1 / 1.2.11 |
嗯,这里要注意一点。MySQL 驱动版本别乱选。我曾经遇到一个线上事故:Flink 任务每隔 2 小时就断连一次,排查到最后发现是 MySQL 驱动 8.0.26 和 Flink JDBC 连接器之间有连接池泄漏的 bug。升到 8.0.28 就好了。
2.5 Gradle 项目初始化(备选)
如果你团队用 Gradle,我也给你准备了配置。我个人其实更倾向 Maven,但 Gradle 的增量编译确实快。
plugins {
id 'java'
id 'application'
}
group 'com.yourcompany'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
// Flink 核心
implementation 'org.apache.flink:flink-java:1.14.4'
implementation 'org.apache.flink:flink-streaming-java_2.12:1.14.4'
implementation 'org.apache.flink:flink-clients_2.12:1.14.4'
// 连接器
implementation 'org.apache.flink:flink-connector-jdbc_2.12:1.14.4'
implementation 'org.apache.flink:flink-connector-kafka_2.12:1.14.4'
// MySQL 驱动
implementation 'mysql:mysql-connector-java:8.0.28'
// 日志
implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
}
application {
mainClass = 'com.yourcompany.MetaSyncJob'
}
implementation 替代 Maven 的 provided。但打包时记得用 shadowJar 插件排除 Flink 核心依赖,否则提交到集群会报 ClassNotFoundException。
2.6 依赖冲突排查
说实话,Flink 开发里最烦人的就是依赖冲突。你想想看,一个任务本地跑得好好的,提交到集群就报 NoSuchMethodError 或 ClassNotFoundException,多半是依赖打架了。
我总结了一套排查流程:
- 用 Maven Helper 插件 — 在 IDEA 里打开
pom.xml,点Dependency Analyzer,看有没有红色冲突线。 - 执行
mvn dependency:tree— 把依赖树打出来,手动检查 Flink 相关 jar 的版本。 - 排除传递依赖 — 比如 Kafka 连接器可能会带一个旧版的 Jackson,和 Flink 自带的冲突。用
<exclusions>排除掉。
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_2.12</artifactId>
<version>${flink.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</exclusion>
</exclusions>
</dependency>
flink-sql-connector-hive 里排除了 guava,用 Hive 自带的版本才解决。
2.7 本地运行验证
环境搭好之后,写个最简单的 WordCount 跑一下,验证整个链路通不通。
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
public class EnvironmentCheck {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.fromElements("Flink", "Meta", "Sync", "Flink")
.keyBy(word -> word)
.sum(1)
.print();
env.execute("Environment Check Job");
}
}
跑起来之后,控制台应该能看到类似这样的输出:
(Flink,2)
(Meta,1)
(Sync,1)
如果报 NoClassDefFoundError,八成是依赖 scope 没设对。把 provided 临时改成 compile 再试一次,确认是依赖问题后,再改回去。
2.8 本章小结
这一章我们干了三件事:配好了 JDK 和 IDE,用 Maven(或 Gradle)初始化了项目,引入了元数据同步需要的核心依赖。你想想看,这些步骤虽然基础,但每一步都踩过坑的人才知道有多重要。