先准备这些基础环境:

先准备这些基础环境:
  • JDK 8 或 11
  • Git
  • JetBrains / IDEA
  • Maven

这些工具的安装这里就不展开了。如果你本身在写 Java,这一段一般都不陌生。

补一句和 Windows 有关的提醒:

  • 如果你要调试 Hive、Iceberg 这类连接器,后面很可能会碰到HADOOP_HOMEwinutils的问题,文末会单独讲。

2. Fork 仓库并克隆代码

仓库位置可以从官方文档直接跳转:

官方仓库:

https://github.com/apache/seatunnel

Fork 完以后,你自己的仓库地址会类似这样:

https://github.com/LeonYoah/seatunnel.git

为什么建议先 fork:

  • 后面提交自己的改动更方便
  • 不会直接影响官方仓库
  • 如果要提 PR,这也是更常见的做法

如果网络不太稳定,可以借助代理地址:

git clone https://cdn.gh-proxy.org/https://github.com/LeonYoah/seatunnel.git cd seatunnel git checkout 2.3.13-release

如果本地提示没有这个分支,可以先把官方仓库加成上游:

git remote add upstream https://cdn.gh-proxy.org/https://github.com/apache/seatunnel.git git fetch upstream --prune git checkout 2.3.13-release

补充一个常用地址,平时能直接记一下:

https://gh-proxy.com/

3. Maven 编译和 IDEA 设置

先用 IDEA 打开seatunnel项目,然后到Project Structure里把 JDK 指到JDK 8

然后再看 Maven 设置。

如果你接受把依赖装到系统默认位置,C 盘,且网络环境很好,这一步其实可以简单一点,因为 IDEA 自带 Maven。
如果你想单独指定 Maven 路径,可以先安装自己的 Maven,然后在$MAVEN_HOME/conf/settings.xml里配镜像。下面这份只是参考,本地仓库路径记得换成你自己的:

<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository>D:\apache-maven-3.8.6\ck</localRepository> <proxies> </proxies> <servers> </servers> <mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> <mirror> <id>repo1</id> <mirrorOf>central</mirrorOf> <name>central repo</name> <url>http://repo1.maven.org/maven2/</url> </mirror> <mirror> <id>repo2</id> <name>Mirror from Maven Repo2</name> <url>https://repo.spring.io/plugins-release/</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <profiles> </profiles> </settings>

然后再到 IDEA 设置里确认:

这里有一项容易漏:

  • use settings from .mvn/config记得取消勾选

接着执行下面两个命令:

# 代码格式化 mvn spotless:apply # 编译安装 mvn clean install -Dmaven.test.skip=true -T 1C

编译完成以后,就可以开始本地调试了。

4. 从 example 模块起调

常用启动类:

org.apache.seatunnel.example.engine.SeaTunnelEngineLocalExample

先改启动配置:

provided带上:

然后点击Shorten command line,选择JAR manifest

最后用Debug模式运行:

5. 用自己的配置文件启动

代码里有这样一行:

String configurePath = args.length > 0 ? args[0] : "/examples/fake_to_console.conf";

这行代码的意思很直接:

  • 如果你启动时传了参数,就读你传入的配置文件
  • 如果没传,就默认读/examples/fake_to_console.conf

所以,自己的配置文件一般放到examples目录下最省事:

6. 实战案例:pg cdc 报错怎么查、怎么修

这里拿一个真实问题举例。

群里有人反馈pg cdc任务报错:

原始堆栈:

at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceSplitReader.fetch(IncrementalSourceSplitReader.java:94) at org.apache.seatunnel.connectors.seatunnel.common.source.reader.fetcher.FetchTask.run(FetchTask.java:54) ... 7 more Caused by: org.apache.seatunnel.common.utils.SeaTunnelException: Read split SnapshotSplit(tableId=traffic.public.users, splitKeyType=ROW<id INT>, splitStart=null, splitEnd=null, lowWatermark=null, highWatermark=null) error due to java.lang.NullPointerException. at org.apache.seatunnel.connectors.cdc.base.source.reader.external.IncrementalSourceScanFetcher.checkReadException(IncrementalSourceScanFetcher.java:216) at org.apache.seatunnel.connectors.cdc.base.source.reader.external.IncrementalSourceScanFetcher.pollSplitRecords(IncrementalSourceScanFetcher.java:117) at org.apache.seatunnel.connectors.cdc.base.source.reader.IncrementalSourceSplitReader.fetch(IncrementalSourceSplitReader.java:91) ... 8 more Caused by: io.debezium.DebeziumException: java.lang.NullPointerException at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotSplitReadTask.execute(PostgresSnapshotSplitReadTask.java:112) at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotFetchTask.execute(PostgresSnapshotFetchTask.java:65) at org.apache.seatunnel.connectors.cdc.base.source.reader.external.IncrementalSourceScanFetcher.lambda$submitTask$0(IncrementalSourceScanFetcher.java:96) ... 5 more Caused by: java.lang.NullPointerException at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotSplitReadTask.createDataEventsForTable(PostgresSnapshotSplitReadTask.java:183) at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotSplitReadTask.createDataEvents(PostgresSnapshotSplitReadTask.java:170) at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotSplitReadTask.doExecute(PostgresSnapshotSplitReadTask.java:136) at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotSplitReadTask.execute(PostgresSnapshotSplitReadTask.java:107) ... 7 more

这类问题,有明确报错的,我们第一反应 应该先看堆栈里最靠后的Caused by。很多时候,最后一个Caused by才是最原始的异常来源。

这次堆栈里最关键的信息其实是:

Caused by: java.lang.NullPointerException at org.apache.seatunnel.connectors.seatunnel.cdc.postgres.source.reader.snapshot.PostgresSnapshotSplitReadTask.createDataEventsForTable(PostgresSnapshotSplitReadTask.java:183)

看到这里,排查思路就清楚了:

  1. 先定位到具体文件和行号
  2. 在 IDEA 里打断点
  3. 用本地环境把问题复现出来
  4. 顺着调用链看变量为什么会是空

在 IDEA 里按两次Shift,搜索