Canal 升级 jar 包操作文档(以升级 FastJSON 为例)

Canal 升级 jar 包操作文档(以升级 FastJSON 为例)

文档背景:生产 Canal 集群使用的 FastJSON 版本存在已知反序列化漏洞(如 CVE-2022-25845),需要升级 jar 包修复。本文以 FastJSON 升级为例,完整记录 Canal jar 包升级的流程、命令、验证方式及踩坑记录。

脱敏说明 :本文为脱敏版本,涉及环境地址、域名、IP、账号密码、部署路径等敏感信息均已替换为占位符(<...>),结构与操作命令完整保留,可直接套用到其他环境。


1. 文档说明

1.1 适用范围

  • Canal 1.1.x 系列(canal.deployer + canal.admin)
  • 部署方式:二进制 tar.gz 解压部署
  • 本文实例环境:Canal 1.1.5,admin manager 管理模式

1.2 环境信息(本文操作环境)

项目 说明
Canal 版本 1.1.5(deployer + admin)
部署目录 /opt/canal/server(Canal Server)
/opt/canal/admin(Canal Admin)
管理模式 admin manager 模式(实例配置下发自 admin)
admin 地址 http://<canal-admin域名>:8089
admin 数据库 <admin数据库主机>:3306 / 库名 <库名>
实例数量 多个(如 <实例名> 等)

1.3 升级前必须知道的两件事

  1. admin 管理模式 :实例配置(instance.properties)存在 admin 数据库中,由 admin 下发到 Canal Server。本地 conf/ 目录下默认只有 example 实例,不要在本地改实例配置(改了不生效)。
  2. jar 升级不影响消费端:Canal Server 与消费端通过 TCP/Kafka 传输的是 protobuf 格式,不依赖 FastJSON 序列化,升级 Server 侧 jar 不影响下游消费端 SDK。

2. 升级方案选择

方案一:FastJSON 1.2.84(推荐,本次实际采用)

  • 1.x 系列的最终修复版本,补齐了主要反序列化漏洞。
  • 包名不变 (com.alibaba.fastjson.*),零代码改动,风险最低。
bash 复制代码
# 下载地址
https://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.84/fastjson-1.2.84.jar

方案二:FastJSON 2.x(2.0.51)+ 兼容包

  • 彻底修复、长期维护,但需要额外引入 fastjson2-extension 兼容包才能兼容老包名。
  • 老代码如果使用 com.alibaba.fastjson.* 包名,必须两个 jar 同时放入 lib。
bash 复制代码
https://repo1.maven.org/maven2/com/alibaba/fastjson2/fastjson2/2.0.51/fastjson2-2.0.51.jar
https://repo1.maven.org/maven2/com/alibaba/fastjson2/fastjson2-extension/2.0.51/fastjson2-extension-2.0.51.jar

结论:生产环境优先选择方案一(1.2.84),稳定后再评估 2.x。


3. 操作步骤

3.1 升级前检查:确认当前 FastJSON 版本与位置

bash 复制代码
cd /opt/canal/server
find . -name "fastjson*.jar"

cd /opt/canal/admin
find . -name "fastjson*.jar"

重点:fastjson jar 可能出现在多个位置,必须全部替换,否则类加载优先命中旧版本,升级失效:

复制代码
server/lib/fastjson-1.2.xx.jar
server/plugin/<插件>/lib/fastjson-1.2.xx.jar   # 如有
admin/lib/fastjson-1.2.xx.jar

3.2 停止服务

先停 Canal Server,再停 Canal Admin(升级两个组件时):

bash 复制代码
cd /opt/canal/server
sh bin/stop.sh

cd /opt/canal/admin
sh bin/stop.sh

# 确认无残留进程
jps -l | grep -i canal

⚠️ 踩坑记录:stop.sh 依赖 PID 文件(logs/canal.*.pid)。若 PID 文件残留(进程被 kill -9 或服务器重启过),stop.sh 会报 kill: (xxxxx) - No such process 并提示 "is not running",但真实进程仍在。此时必须:

bash 复制代码
# 用 jps 找到真实进程 PID
jps -l | grep -i canal
kill <真实PID>
# 确认停止后再清理残留 PID 文件
rm -f /opt/canal/admin/logs/canal.admin.pid

3.3 备份旧 jar

bash 复制代码
cd /opt/canal
mkdir -p backup/fastjson-bak

find server admin -name "fastjson*.jar" \
  -exec cp -p {} backup/fastjson-bak/ \;

ls -l backup/fastjson-bak/

3.4 下载新版本 jar

有外网环境直接下载:

bash 复制代码
cd /opt/canal/server/lib
wget https://repo1.maven.org/maven2/com/alibaba/fastjson/1.2.84/fastjson-1.2.84.jar

说明:公共 Maven 中央仓库的 fastjson 1.x 系列版本只发布到 1.2.83,若按上述地址下载不到 1.2.84,请从公司内部 Maven 仓库/离线包获取(实际升级的 1.2.84 jar 来源以实际部署为准),URL 拼接规则一致。

无外网环境(生产常见),在本地下载后 scp 上传:

bash 复制代码
# 本地执行
scp fastjson-1.2.84.jar <账号>@<服务器>:/opt/canal/server/lib/

3.5 替换所有位置的 jar

bash 复制代码
cd /opt/canal

# 先列出所有待替换位置(以实际输出为准)
find server admin -name "fastjson*.jar"

# 1. 替换 server/lib
rm -f server/lib/fastjson-*.jar
cp server/lib/fastjson-1.2.84.jar server/lib/

# 2. 替换 plugin 下各插件目录(如有)
for d in server/plugin/*/lib; do
  rm -f "$d"/fastjson-*.jar
  cp server/lib/fastjson-1.2.84.jar "$d"/
done

# 3. 替换 admin/lib
rm -f admin/lib/fastjson-*.jar
cp server/lib/fastjson-1.2.84.jar admin/lib/

验证替换结果:

bash 复制代码
find server admin -name "fastjson*.jar" -exec ls -l {} \;

应全部显示为 fastjson-1.2.84.jar,无旧版本残留。

3.6 启动并验证

bash 复制代码
# 先启动 admin(server 依赖 admin 下发配置)
cd /opt/canal/admin
sh bin/startup.sh
sleep 5
tail -f logs/admin.log

# 再启动 server
cd /opt/canal/server
sh bin/startup.sh
sleep 5
tail -f logs/canal/canal.log
tail -f logs/example/example.log

# 进程确认
jps -l | grep -i canal

重点关注日志是否出现:

  • ClassNotFoundException: com.alibaba.fastjson.JSON → 新 jar 未放入对应目录
  • NoSuchMethodException / NoClassDefFoundError → 有目录仍残留旧 jar,需再清理
  • 实例日志出现 start successful....、find start position successfully → 正常

3.7 功能回归验证

  1. 登录 canal-admin Web,确认各实例状态为「启动」、实例列表正常。
  2. 在各实例对应的源库执行一条变更(增/删/改),确认下游消费端能正常收到数据。
  3. 观察 24 小时,确认无 OOM、无异常日志。

4. 常见问题

4.1 stop.sh 报 No such process,但进程还在

见 3.2 踩坑记录:PID 文件残留。用 jps 找真实 PID 手动 kill,并清理 PID 文件。务必等 jps 确认停干净再操作,否则替换 jar 后启动会异常。

4.2 启动报 ClassNotFoundException / NoSuchMethodException

大概率是某个目录的 fastjson jar 没替换到。执行:

bash 复制代码
find /opt/canal/server /opt/canal/admin -name "fastjson*.jar"

确认所有位置的 jar 版本一致;若混放 1.2.x 与 2.x 的 jar,删除多余的旧版本。

4.3 服务器没有外网 / 没有 mysql 客户端

  • 无外网:本地下载后 scp 上传(见 3.4)。
  • 无 mysql 客户端(操作 admin 库需要时):sudo yum install -y mariadb 临时安装。

4.4 升级后实例报错,需要回滚

bash 复制代码
# 停止
sh bin/stop.sh
# 用 3.3 备份的旧 jar 还原
cp backup/fastjson-bak/fastjson-1.2.xx.jar lib/
# 启动
sh bin/startup.sh

5. 经验总结

  1. 替换前必须完整停服(包括 admin),替换后先 admin 后 server 的顺序启动。
  2. fastjson jar 位置多 ,一定用 find 全量定位后再替换,避免漏替换导致类冲突。
  3. admin manager 架构下,实例配置在库里不在本地 :不要在本地 conf/ 改实例配置;升级 jar 也不需要动任何实例配置。
  4. 升级 jar 包与实例位点(cursor)无关:如果升级后实例报 binlog 相关错误(如 errno 1236),是位点失效问题,不是 jar 升级导致,需按位点重置流程处理(见《Canal GTID 位点失效解决方案》)。
  5. 升级前务必备份(旧 jar、实例配置),保证可回滚。

附录 A:FastJSON 漏洞背景(为什么升级)

FastJSON 1.2.x 系列存在多个反序列化 RCE 漏洞(如 CVE-2022-25845,com.alibaba.fastjson 1.2.80 及以下受影响),漏洞在 1.2.83/1.2.84 与 2.x 中修复。Canal 内置的 FastJSON 版本较旧(1.2.28 ~ 1.2.58),属于受影响范围,故需升级。实际生产升级采用 FastJSON 1.2.84。

附录 B:本文相关命令速查

bash 复制代码
# 全量定位 fastjson jar
find /opt/canal -name "fastjson*.jar"

# 停止与确认
sh bin/stop.sh && jps -l | grep -i canal

# 备份
find server admin -name "fastjson*.jar" -exec cp -p {} backup/fastjson-bak/ \;

# 替换(server/lib 示例)
rm -f server/lib/fastjson-*.jar
cp fastjson-1.2.84.jar server/lib/

# 启动与看日志
sh bin/startup.sh
tail -f logs/canal/canal.log
相关推荐
Sayai11 分钟前
Neo4j 内嵌模式(Embedded)实战:Java 嵌入式 vs 服务端部署的写入性能对比与 GC 调优
java·开发语言·性能优化·neo4j·图数据库
木头科技20 分钟前
AI 工程化第四篇】Spring AI Agent 线上可观测实战:Token 成本、调用链、工具耗时、RAG 命中率怎么监控
java·人工智能·spring
m0_7341724228 分钟前
Python列表切片为什么不改变原列表
java
kiss strong31 分钟前
idea显示前进后退按钮
java·ide·intellij-idea
caoerzhong1 小时前
跨境海外仓怎么管:JeeWMS 开源 Java 仓库管理系统打通头程、海外仓与尾程
java·开发语言·开源
MayBaymax1 小时前
Elasticsearch 原理与用法
java·elasticsearch
马剑威(威哥爱编程)1 小时前
【AI全栈后端12-02】Spring Boot 跑通第一个 AI 对话接口:HR 政策问答机器人实战
java·人工智能·spring boot·机器人
IT枫斗者枫哥1 小时前
AI返回合法JSON,字段就可信吗?给抽取结果补一道业务校验
java·人工智能·后端
用户3126874877201 小时前
Java IO/NIO/AIO 演进:从 BIO 到 Netty 的底层逻辑
java
IT枫斗者枫哥1 小时前
同一个requestId换了参数,为什么不能直接返回旧结果?
java·后端