← 返回博客
Canal · 开源 · 调试 · 中间件

从零开始调试 Canal:一个真实的踩坑记录

·9 分钟阅读

作者:一个刚踩完坑的新手 时间:2026-03-09 背景:想参与 Canal 开源项目的小白

前言

最近想参与开源项目,因为自己的项目用到了这个Canal组件(MySQL binlog 增量订阅组件),所以就选了从它入手。本想着 “不就是拉代码、编译、跑起来嘛”,结果踩了一堆坑。记录下来,给后来者避坑。

第一步:编译项目

坑 1:GPG 签名报错

按照 README 执行:

mvn clean install -DskipTests

结果报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:3.2.8:sign

只是想本地调试,签什么名啊?

解决:加上 -Dgpg.skip=true

mvn clean install -DskipTests -Dgpg.skip=true

坑 2:PowerShell 解析问题

如果你用 Windows PowerShell,直接复制命令可能报错:

[ERROR] Unknown lifecycle phase ".skip=true"

这是因为 PowerShell 把 -Dgpg.skip=true 解析错了。

解决:用引号包裹参数

mvn clean install "-DskipTests" "-Dgpg.skip=true"

或者直接用 CMD:

mvn clean install -DskipTests -Dgpg.skip=true

坑 3:Java 版本参数报错(Windows 用户专属)

编译通过后,用 startup.bat 启动 Canal Server:

.\startup.bat

结果:

Unrecognized VM option 'PermSize=128m'
Error: Could not create the Java Virtual Machine.

-XX:PermSize 是 Java 7 的参数,Java 8+ 已经改成 MetaspaceSize 了。

解决:修改 deployer/target/canal/bin/startup.bat(注意是 target 里的,不是 src 里的)

# 把这一行
set JAVA_MEM_OPTS= -Xms128m -Xmx512m -XX:PermSize=128m

# 改成
set JAVA_MEM_OPTS= -Xms128m -Xmx512m -XX:MetaspaceSize=128m

教训:开源项目的启动脚本可能年久失修,特别是 Windows 的 .bat 文件。

第二步:配置 MySQL 连接

坑 4:配置不生效

我修改了 deployer/src/main/resources/example/instance.properties:

canal.instance.master.address=ip:3306
canal.instance.dbUsername=root
canal.instance.dbPassword=123456

启动后看日志,发现 Canal 还是在连 127.0.0.1:3306!

内心OS:明明修改了配置为什么还有问题!

解决:原来 Canal 运行时用的是一个独立的 target/canal/conf 目录,不是 src/main/resources!

有两个办法:

  • 改 deployer/target/canal/conf/example/instance.properties(临时调试用)

  • 或者改完 src 的重新打包(正式做法)

我选了第一种,终于看到日志里显示连接 192.168.12.168:13306 了。

日志验证:

2026-03-09 18:39:58.703 [...] find start position successfully,
EntryPosition[...j,ournalName=binlog.000005,position=334...]

看到 find start position successfully 就说明连上 MySQL 了。

第三步:IDE 调试

坑 5:断点打不上

想 debug 看看代码怎么走的,结果 IDE 里打断点没用,显示空心圆圈。

查了半天,发现是 VSCode 的 Java 项目没识别好。

解决:

  • 确保安装了 “Extension Pack for Java”

  • 执行 mvn clean compile -DskipTests -Dgpg.skip=true 生成 class 文件

  • 重启 VSCode,等右下角 “Java 项目加载完成” 的提示消失

然后配置 .vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "Debug Canal Server",
            "request": "launch",
            "mainClass": "com.alibaba.otter.canal.deployer.CanalLauncher",
            "projectName": "canal.deployer",
            "cwd": "${workspaceFolder}/deployer/target/canal",
            "vmArgs": [
                "-Dcanal.conf=${workspaceFolder}/deployer/target/canal/conf/canal.properties"
            ]
        },
        {
            "type": "java",
            "name": "Debug Canal Client",
            "request": "launch",
            "mainClass": "com.alibaba.otter.canal.example.SimpleCanalClientTest",
            "projectName": "canal.example"
        }
    ]
}

终于能打断点了! 注:这个不太确定,大家最好结合AI工具试试,虽然我是成功了,但不确保其他机子成功。

第四步:理解代码

为了能参与贡献,我开始看 filter 模块的代码。

发现 AviaterRegexFilter 用了一个叫 Aviator 的表达式引擎。简单说就是把正则配置编译成表达式,然后执行。

代码大概长这样:

public boolean filter(String tableName) {
    Map<String, Object> env = new HashMap<>();
    env.put("pattern", "^test\\..*$|^order\\..*$");
    env.put("target", tableName.toLowerCase());
    return (Boolean) exp.execute(env);  // 执行 Aviator 表达式
}

看了下代码,其实exp.execute就相当于list查找有没有当前字符串,只是用这个Aviator组件包装了一下

调试技巧:

  • 在 AviaterRegexFilter 构造函数打断点,看 pattern 怎么被处理

  • 在 filter() 方法打断点,看正则匹配过程

我还发现了一些潜在问题,比如:

  • 每次调用都创建 HashMap(性能可优化)

但这些都是后话了,先跑起来再说。

总结:给新手的建议

问题 解决方案

GPG 签名报错 加 -Dgpg.skip=true

PowerShell 解析错误 参数用引号包裹,或用 CMD

Java 参数错误 改 PermSize 为 MetaspaceSize

配置不生效 改 target/canal/conf 下的文件

断点打不上 确保 Java 项目加载完,配置 launch.json

关键目录结构:

canal/
├── deployer/src/main/resources/    # 源码配置(改完要重新打包)
├── deployer/target/canal/          # 运行时目录(调试时改这里)
│   ├── bin/startup.bat             # Windows 启动脚本
│   ├── conf/canal.properties       # 运行时配置
│   └── logs/                       # 日志目录
└── filter/src/...                  # 模块源码(可以调试)

查看日志:

# 服务端日志
cat deployer/target/canal/logs/canal/canal.log

# 实例日志(最重要)
cat deployer/target/canal/logs/example/example.log

参与开源项目第一步总是最难的,但只要跑起来,后面就顺了。

祝大家少踩坑,多贡献!

相关链接

查看全部文章 →