# V8大版本整体升级后的回滚操作步骤

# 文档目的

当V8微服务版本升级后出现重大功能异常、数据兼容性问题或性能不可接受时,按本手册将应用、配置、前端资源、数据库、缓存、Kafka消息链路及元数据恢复至升级前已确认可用的备份时间点。

# 1. 回滚原则与影响

项目 要求
回滚触发 经业务变更负责人、项目经理及技术负责人确认;生产环境应完成回滚审批与窗口确认。
数据影响 数据库与Kafka均回滚至备份时间点;该时间点之后产生或已消费的业务数据、消息可能丢失或需补偿
执行顺序 先停止服务,确认无消息消费后,再备份现状数据;恢复数据库、Kafka、配置与应用;最后按依赖顺序启动和验收。
职责分工 应用/运维负责服务与镜像;DBA负责数据库备份与恢复;中间件管理员负责Kafka、Redis、Nacos的备份及恢复;业务方负责验收。

# 2. 回滚前准备与检查清单

序号 检查项 完成标准
1 冻结变更与入口写入 停止业务操作变更、发布流水线、定时任务及外部写入;记录回滚决策时间。
2 确认回滚基线 明确升级前后端镜像版本、部署yaml模板、Nacos配置、前端资源、数据库及Kafka的备份时间点、备份产物及备份可恢复性。
3 停机公告 通知业务、接口调用方及业务方人员;确认维护窗口。
4 备份现状数据 备份当前部署镜像、部署yaml模板、Nacos配置、前端资源、数据库、Kafka、对象存储;确认备份介质可读取及备份可恢复。

# 3. V8微服务回滚实施步骤

序号 操作项 操作说明 执行校色 完成标准
1 停止服务 将本环境的所有微服务副本缩容为0,等待kafka消费者停止 应用/运维 服务副本数为0,kafka无活跃消费者。
2 恢复数据库 DBA 按升级前备份时间点执行数据库恢复;记录备份集、恢复时间、日志与校验结果。 DBA 关键库表可访问,数据与备份点一致
3 恢复Kafka 按第 3 章恢复 Topic 元数据、消息数据、ACL及消费者组位点。 中间件管理员 数据与位点达到批准的回滚基线。
4 清空Reis缓存 在数据库与Kafka回滚完成后执行flushall或flushdb,或按业务约定清理指定前缀的Redis数据。 中间件管理员 缓存清理完成,未误清其他业务。
5 恢复Nacos配置 导入升级前 Nacos 配置;核对 dataId、group、namespace、版本与密钥配置。 应用/运维 配置导入成功并完成差异校验。
6 恢复前端资源 将前端资源备份目录通过对象存储客户端覆盖到公共桶的根目录下。 应用/运维 关键资源版本与升级前一致。
7 回滚后端镜像 按照升级前备份的镜像清单,将Deployment中镜像改回升级前标签。 应用/运维 所有服务镜像与清单一致。
8 启动服务 按平台服务→标准应用服务→低代码服务顺序逐步启动及扩容。 应用/运维 Pod Ready、日志、健康检查正常。
9 回滚元数据 访问/service/app-common/metadata/online-app-info,对每个服务执行downgrade-metadata接口进行元数据降级 应用/运维 检查每个微服务的元数据降级成功,回滚到升级前的版本
10 业务验证与解除管控 验证接口、页面、核心流程、消息消费及数据一致性,审批后解除维护。 业务/测试/项目经理 验收记录完整,结论明确

# 4. 关键命令参考

# 4.1 停止服务

kubectl -n seeyon-dev scale --replicas=0 deployment $(kubectl -n seeyon-dev get deployments.apps | egrep -v 'nginx|NAME')

# 4.2 前端资源回滚

cd /data/20260728-dev-frontend-backup
for i in `ls`; do obsutil cp -r -f --flat $i obs://obs-zjjt-public/$i; done
for i in `ls`; do mc cp -rf  $i/ minio/seeyon-zjjt-public/$i/; done

# 4.3 后端镜像回滚与启动示例

kubectl -n seeyon-dev set image deployment/edoc335172694483814428 edoc335172694483814428=10.6.37.167/seeyonv8/seeyonv8:edoc335172694483814428-5.30.58

# 4.4 Kafka备份恢复操作

4.4.1 备份范围 Kafka 备份必须覆盖:业务 Topic 消息数据、Topic 配置(分区数/副本数/保留策略)、ACL、配额(如有)、消费者组及关键 Group Offset。对变更期间产生的数据,至少保留一份回滚前现场备份,以支持追溯和业务补偿。

对象 备份内容 建议校验
Topic数据 按Topic与分区导出消息;保留 key、value、headers、timestamp、partition、offset。 记录每分区起止 offset、消息数、导出文件校验和
Topic配置 Topic列表、分区/副本数、cleanup.policy、retention等配置 与升级前基线配置对比。
消费者组 组列表、各Topic-Partition已提交offset、消费状态。 导出前后比对关键组位点。
ACL/配额 ACL规则、用户与资源权限、配额设置。 恢复后用业务账号验证消息的生产/消费情况。

停止业务服务后,检查消费者组中目标Topic的每个分区,已提交Offset追上最新Offset,且LAG全部为0,再关闭kafka服务。

常用判断命令:
$KAFKA_HOME/bin/kafka-consumer-groups.sh \
  --bootstrap-server <Kafka地址> \
  --group <消费者组名> \
  --describe
例如:
/data/apps/kafka_2.13-3.9.2/bin/kafka-consumer-groups.sh \
  --bootstrap-server 10.6.6.91:9092 \
  --group order-consumer-group \
  --describe
典型输出:
GROUP           TOPIC              PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG
POC_ctp-message POC_CMD_MSG        0          22              22              0
POC_ctp-message POC_CMD_MSG        1          68              68              0
POC_ctp-message POC_CMD_MSG        2          13              13              0
POC_ctp-message POC_MESSAGE_CENTER 0          1               1               0
当每行的LAG都是0时,代表该消费者组已提交的消费进度已经追平当前消息末尾。

4.4.2 Kafka 迁移操作(示例命令) 注:以下命令为通用示例。实际脚本、Kafka 版本、SASL/SSL 参数、Bootstrap 地址及备份工具以现场标准为准;生产执行前应在非生产或隔离环境演练。 本示例为Kafka的单机到单机间的迁移操作,在所有消费者组均已完成消费后,停止V8服务进行操作 方式一:物理文件备份 直接拷贝Kafka的数据目录和配置文件。

步骤:
a). 停止服务:sudo systemctl stop kafka。如果使用ZooKeeper,也建议一并停止。
b). 备份数据:打包压缩数据目录和配置文件目录(log.dirs通常在kafka安装目录的data目录下和配置文件通常在kafka安装目录的config目录下)。
bash
tar -czvf kafka_backup_$(date +%F).tar.gz /data/apps/kafka/
c). 恢复:停止Kafka,用备份的压缩包覆盖原有目录,并修正文件权限后重启

方式二:使用Kafka官方推荐的跨集群数据复制工具 MirrorMaker 2 (MM2) 进行迁移备份

a). 环境准备
软件要求:在计划运行MM2的机器上,下载并解压与源集群版本兼容的Kafka安装包。
网络要求:确保运行MM2的机器能够同时网络访问源Kafka集群和目标Kafka集群的所有Broker。
b). 创建配置文件
创建MM2的核心配置文件,如mm2-standalone.properties。以下是一个标准配置示例
cat > mm2-standalone.properties <<EOF
clusters=source,target
source.bootstrap.servers=10.6.6.90:9092
target.bootstrap.servers=10.6.6.91:9092

# 仅启用源端到目标端的单向迁移。
# 注意:Kafka 3.9.x 即使 x->y.enabled=false,默认心跳仍可能使 MM2 创建 x->y Herder;
# 因此反向流必须同时关闭其心跳,且启动时用 --clusters target 将本进程限定为目标端 target。
source->target.enabled=true
source->target.emit.heartbeats.enabled=true
target->source.enabled=false
target->source.emit.heartbeats.enabled=false

source->target.topics=.*
source->target.groups=.*

# 目标 Topic 保持与源 Topic 同名。
replication.policy.class=org.apache.kafka.connect.mirror.IdentityReplicationPolicy
source->target.replication.policy.class=org.apache.kafka.connect.mirror.IdentityReplicationPolicy

# 源/目标均为单机 Kafka,所有业务和 MM2 内部 Topic 均只能使用副本数 1。
replication.factor=1
config.storage.replication.factor=1
offset.storage.replication.factor=1
status.storage.replication.factor=1
heartbeats.topic.replication.factor=1
checkpoints.topic.replication.factor=1
offset-syncs.topic.replication.factor=1

# 单机迁移使用单任务;可按吞吐情况调整。
tasks.max=1
plugin.discovery=service_load

# 心跳、offset-sync 与 checkpoint。
emit.heartbeats.enabled=true
emit.heartbeats.interval.seconds=5
emit.offset-syncs.enabled=true
emit.checkpoints.enabled=true
sync.group.offsets.enabled=true
EOF
b). 启动MM2
cd /data/apps/
nohup /data/apps/kafka_2.13-3.9.2/bin/connect-mirror-maker.sh /data/apps/mm2-standalone.properties > ./mm2.log 2>&1 &
d). 验证同步状态
检查主题:在目标集群查看是否已自动创建对应的主题。

4.4.3 Kafka 恢复与消费者位点处理

步骤 操作要求 关键控制点
停止生产与消费 停止所有微服务、Kafka Connect、流处理任务和定时任务。 确认关键消费者组无活跃成员
隔离现网数据 保留升级后Topic数据备份;建议恢复到隔离Kafka集群或以新Topic导入后回切。 未经批准不得直接删除生产Topic
恢复元数据 按升级前基线创建/校验 Topic、分区、副本、配置、ACL与配额。 分区数必须与备份记录、消费者策略兼容。
导入消息 按原 Topic、partition、key/value/headers/timestamp 导入备份。 以分区内顺序为准;核对消息数与校验和。
设置消费位点 按批准策略重置消费者组:备份点 offset 或导入后最早/最晚位点。 避免漏消费或重复消费。
验证并回切 抽查消息、消费者组 lag、生产/消费权限及业务幂等性。 先灰度启动消费者,观察积压和重复处理。

注意:Kafka 原生工具不能将消息原样写回既有offset。如需严格保留offset,必须采用经验证的集群级备份/恢复方案(存储快照、厂商工具或成熟灾备产品)并依其手册执行;重新生产消息时,应通过业务唯一键、时间戳和消费者位点策略控制重复处理。

# 版本回滚操作必读:

基础约束规则

  1. 研发平台未完成全链路版本回滚验证,无紧急特殊故障禁止执行回滚,生产环境原则上不执行回滚。
  2. 若Kafka存在消息积压,且新旧版本消息实体结构不同,回滚至旧版本可能会造成旧程序消息反序列化失败,出现消息堆积、脏数据、业务错乱等现象。
  3. 回滚操作会将数据库、对象存储、Kafka全部还原至备份时间点:备份时点之后新增的业务数据、已消费消息存在丢失风险,部分业务可人工补数;升级功能验证阶段定时任务自动生成的数据,回滚后永久无法找回。

额外重要风险与强制要求

  1. 若新版本包含数据库DDL表结构变更,回滚不仅会丢失增量数据,还会出现表结构版本不兼容,程序执行 SQL 直接报错。
  2. 硬性前置要求:执行回滚操作前,必须对当前全量业务数据做二次备份,防止回滚故障无数据兜底。
  3. Kafka消费偏移量不能逆向回退,已经消费完毕的消息无法恢复;只有队列内未消费消息支持依靠偏移量重放补救。
    编撰人:chongfk、het