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
相关推荐
刘 大 望10 小时前
Agent 的规划与执行范式:Plan-Execute-Replan 与 ReAct
java·python·ai·chatgpt·langchain·ai编程
const_qiu10 小时前
第四章 05:4.5 Multi-Agent —— 五个专职智能体协作
java·人工智能
A小码哥10 小时前
大模型成本怎么降,5 个动作先做前两个
java·前端·spring
鬼手点金10 小时前
构建有效 Agent 的核心原则
java·人工智能·git·学习·自动化
神魔皆以血嗜11 小时前
Java 实现简单状态机(订单状态流转)
java·后端
随性而行36011 小时前
企业微信 API 如何实现业务消息自动通知?接口应用场景解析
java·人工智能·后端·微信·机器人·企业微信
姜九笙56111 小时前
python学习---归来仍是新人
java·python·学习
HEJOO911 小时前
Java 并发运行中的安全问题详解
java·开发语言
2601_9621066411 小时前
【无标题】
java·idea
汉吉龙测控技术11 小时前
激光对中仪作用介绍(AS 激光对中仪)
java