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.shNo 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
相关推荐
后台模板学习1 小时前
学习的心态高频面试题
java·数据库·学习
用户3126874877202 小时前
线程池到底怎么管理线程的?从 ThreadPoolExecutor 到拒绝策略全链路拆解
java
cpolar技术支持2 小时前
Kafka Streams 窗口统计怎么验收:本地跑订单流聚合,用 cpolar 给同事看只读结果页
java·docker·kafka·cpolar·kafka streams
爱读源码的大都督2 小时前
DeepSeek面试官问:生产RAG系统回答不准确,该如何定位和优化?这样回答,能让面试官当场给你Offer!
java·后端·python
杨运交2 小时前
[069][公共模块]Spring Boot 全局异常处理与参数校验实战(下):校验异常精细化处理与 WebFlux 适配
java·spring boot·后端
Raas1003 小时前
MAI Gateway(魔芋企业级AI网关)对比分析:AI网关和OpenRouter区别?企业级能力差距一览
java·服务器·网络·人工智能·gateway·ai网关·mai gateway
APItesterCris3 小时前
告别人工盯品!借助 Open‑Claw 快速搭建电商商品全自动监控与数据分析系统(完整实操代码)
java·大数据·前端·数据库
青山木3 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法
ly76893 小时前
Spring 中的 @Configuration 与 @Component 差异:为何代理时机决定 Bean 生命周期行为
java·后端·spring·注解·代理·bean生命周期