后端应用升级
本脚本 (bp-cloud-upgrader.sh) 是用于 basic-paper-cloud-server 及其相关微服务模块的自动化增量升级工具。它支持多实例部署场景,具备自动备份、服务启停、配置文件智能合并及版本管理功能。
下载脚本:bp-cloud-upgrader.tar.gz 最近更新于 2026-4-25 v1.1.0
重要
- 升级脚本文件 (
bp-cloud-upgrader.sh) 必须放置在已安装程序的同级目录下。 - 虽然脚本支持停止服务流程,但由于现场环境复杂,仍建议手动停止服务后再进行升级操作。
快速了解
这个脚本能做什么?
- 增量升级:只升级你已经安装的模块,未安装的模块不会被自动添加。
- 多实例支持:自动识别并升级多实例部署的服务(如 IVR、软电话服务等)。
- 安全不覆盖:配置文件智能合并,保留你的自定义配置值;已存在的 lib 库文件不会被覆盖。
- 自动清理:升级模块时自动删除旧版本 jar,避免残留堆积。
- 自动备份:升级前自动备份当前程序到
backup/目录,可随时回滚。 - 启动验证:升级完成后可选择自动启动服务,并验证进程是否成功启动。
执行升级时会发生什么?
当你运行 ./bp-cloud-upgrader.sh upgrade <升级包> 时,脚本将按以下顺序执行:
- 解压升级包 → 校验包内容完整性。
- 检测升级范围 → 对比你已安装的模块与升级包中的模块,确定哪些需要升级。
- 停止服务 → 停止需要升级的服务实例(可跳过)。
- 备份程序 → 将当前程序备份到
backup/目录(可跳过)。 - 更新文件 → 更新启动脚本、智能合并配置文件、新增 lib 库文件、先删后装 modules jar。
- 启动服务 → 询问是否启动已升级的服务,启动后会验证进程状态并给出结果。
整个过程中,你的日志、JDK、自定义配置值都不会被改动。如果升级出现问题,可以从
backup/目录恢复。
五分钟上手
# 1. 将脚本和升级包放到程序同级目录
# 2. 先预演,看看会升级哪些模块
./bp-cloud-upgrader.sh -d upgrade basic-paper-cloud-server-x.x.x.tar.gz
# 3. 确认无误后,正式执行升级
./bp-cloud-upgrader.sh upgrade basic-paper-cloud-server-x.x.x.tar.gz
# 4. 升级完成后按提示选择是否启动服务1. 运行环境与前置条件
在执行脚本前,请确保满足以下环境要求:
- 操作系统:Linux (支持 Bash 环境)
- 目录结构:脚本必须放置在已安装程序的同级目录下。
- 文件位置:升级包(
.tar.gz)也必须放置在该脚本所在的同级目录下。 - 权限要求:执行用户需对程序目录拥有读写权限。
标准目录结构示例:
/path/to/deploy/
├── bp-cloud-upgrader.sh # 本升级脚本
├── basic-paper-cloud-server # 已安装的程序目录
│ ├── bin/ # 启动脚本目录
│ ├── conf/ # 配置文件目录
│ └── ...
├── basic-paper-cloud-server-x.x.x.tar.gz # 升级包
└── backup/ # (可选) 备份目录 (脚本会自动创建)2. 升级判定逻辑详解
该脚本并不是"盲目"地把升级包里的所有文件覆盖到旧目录中,而是遵循一套"存在即更新,多实例需映射"的规则。
2.1 什么时候会执行升级? (触发条件)
脚本判定一个模块需要升级,必须同时满足以下两个条件:
条件 A:旧系统中存在该模块的启动脚本
- 脚本会扫描旧目录
basic-paper-cloud-server/bin/。 - 必须存在名为
startup-<模块名>.sh或startup-<模块名><数字>.sh的文件。 - 注意:纯数字的脚本(如
startup-1.sh)会被忽略,不视为有效服务。
- 脚本会扫描旧目录
条件 B:升级包中存在该模块的基础模板
- 脚本会检查解压后的升级包目录。
- 必须存在对应的
startup-<基础模块名>.sh模板文件。 - 这里的"基础模块名"是指剔除数字后的名字(例如
crystal-call-ivr)。
✅ 典型升级场景示例:
| 场景描述 | 旧系统状态 (Installed) | 升级包内容 (Package) | 结果 |
|---|---|---|---|
| 标准单实例升级 | 存在 startup-user-center.sh | 包含 startup-user-center.sh | 会升级 (直接覆盖) |
| 多实例升级 | 存在 startup-crm-1.sh 和 startup-crm-2.sh | 包含 startup-crm.sh | 会升级 (用包里的 crm.sh 模板,去重写生成旧目录的 crm-1.sh 和 crm-2.sh) |
| 混合模式 | 存在 startup-order.sh (主) 和 startup-order-1.sh (实例) | 包含 startup-order.sh | 会升级 (主实例和子实例都会被更新) |
2.2 什么时候不会升级? (跳过逻辑)
如果出现以下情况,脚本会跳过该文件的更新,保留旧版本文件:
情况 1:旧系统中没有安装该模块
- 场景:升级包里新增了一个
new-feature.jar,但旧目录里没有对应的startup-new-feature.sh。 - 结果:脚本不会自动创建新服务,也不会复制该模块的 jar 文件。该模块将被完全跳过,不会在本次升级摘要中显示为"已更新"。
- 场景:升级包里新增了一个
情况 2:旧系统中已存在该库文件 (针对 Lib 目录)
- 场景:升级包中的
.jar或.so文件在旧目录的lib/中已经存在同名文件。 - 结果:脚本不会覆盖已存在的文件,仅当文件不存在时才会新增。
- 场景:升级包中的
情况 3:配置文件的值已被修改
- 场景:升级包中的
app.conf某一行是PORT=8080,但旧配置文件中被管理员改为了PORT=9090。 - 结果:脚本执行智能合并。它会保留旧的
PORT=9090,不会将其覆盖回8080,但会提示配置值不同,保留现有配置。
- 场景:升级包中的
情况 4:多实例命名不规范
- 场景:旧目录有一个
startup-abc.sh,但升级包里只有通用的模板,且abc不在脚本预设的多实例白名单中(目前是crystal-call-ivr,crystal-call-phone)。 - 结果:如果升级包里没有专门的
startup-abc.sh,这个实例将不会被更新。
- 场景:旧目录有一个
2.3 特殊文件处理策略表
为了让你一目了然,以下是脚本对不同类型文件的处理逻辑:
| 文件类型 | 判定逻辑 | 行为描述 |
|---|---|---|
启动脚本(.sh) | 严格匹配 | 仅当旧脚本对应的"基础服务名"在升级包中存在时,才会更新。多实例脚本会基于主模板重写。 |
配置文件(.conf, .properties) | 智能合并 | 仅当旧文件存在时执行合并。绝不覆盖旧配置的自定义值,只添加新键或新注释。 |
库文件(.jar, .so 等) | 仅新增 | 仅当文件不存在时才新增,已存在的文件一律跳过,不做覆盖。 |
模块Jar(modules/) | 先删后装 | 先删除旧版本的 jar 文件(按服务名模糊匹配),再安装新版本 jar。 |
日志目录(logs/) | 完全忽略 | 既不备份,也不从升级包复制,完全保留原样。 |
JDK目录(jdk/) | 完全忽略 | 既不备份,也不更新,防止破坏运行环境。 |
2.4 总结
- 它会更新:你正在用的服务(包括多实例),以及它们的模块 jar 文件(自动清理旧版本)。
- 它不会动:你没装的服务、你的日志、你的 JDK、你手动改过的配置数值,以及已存在的 lib 库文件。
3. 常用命令速查表
| 命令 | 说明 | 示例 |
|---|---|---|
upgrade | 执行增量更新 | ./bp-cloud-upgrader.sh upgrade pkg.tar.gz |
list | 列出已安装模块 | ./bp-cloud-upgrader.sh list |
backup | 手动备份当前程序 | ./bp-cloud-upgrader.sh backup |
version | 显示脚本版本 | ./bp-cloud-upgrader.sh version |
help | 显示帮助信息 | ./bp-cloud-upgrader.sh help |
4. 详细使用说明
4.1 升级操作 (upgrade)
这是脚本最核心的功能,用于将系统从旧版本更新到新版本。
基础语法:
./bp-cloud-upgrader.sh [选项] upgrade <升级包文件名>执行流程:
- 解压校验:解压升级包并校验文件完整性。
- 预扫描缓存:扫描升级包中的 jar 文件,构建版本号缓存,避免后续重复检索。
- 服务检测:自动检测当前运行的实例(包括多实例),并与升级包对比确定需要升级的模块。
- 停止服务:默认停止需要更新的服务实例(可选跳过)。
- 自动备份:将当前程序备份至
backup/目录(可选跳过)。 - 文件更新:
- Bin目录:更新启动脚本,支持多实例脚本的自动生成。
- Conf目录:智能合并配置文件,保留旧配置的自定义值,仅添加新配置项。
- Lib目录:仅新增不存在的库文件,已存在的一律跳过。
- Modules目录:先删除旧版本 jar(按服务名模糊匹配),再安装新版本 jar。
- 清理:删除临时解压文件。
- 启动服务:询问是否启动已升级的服务,自动启动并验证进程状态。
示例:
# 标准升级(会提示确认)
./bp-cloud-upgrader.sh upgrade basic-paper-cloud-server-x.x.x.tar.gz
# 自动确认模式(无人值守)
./bp-cloud-upgrader.sh -y upgrade basic-paper-cloud-server-x.x.x.tar.gz
# 预演模式(仅模拟执行,不修改文件系统)
./bp-cloud-upgrader.sh -d upgrade basic-paper-cloud-server-x.x.x.tar.gz4.2 列出已安装模块 (list)
用于查看当前系统中检测到了哪些可启动的服务模块。
使用方法:
./bp-cloud-upgrader.sh list注:该命令会扫描 bin/ 目录下以 startup- 开头的脚本(排除 startup-all.sh),并列出服务名。
4.3 手动备份 (backup)
在进行手动维护前,可以使用此命令手动创建一份当前程序的备份。
使用方法:
./bp-cloud-upgrader.sh backup备份文件将存储在脚本同级目录下的 backup/ 文件夹中,文件名包含时间戳。
4.4 版本与帮助 (version, help)
version:显示脚本当前的版本号 (v1.1.0)。help:显示完整的命令帮助文档。
5. 高级选项 (Flags)
在命令前添加以下选项可以改变脚本的行为:
| 选项 | 全称 | 作用 |
|---|---|---|
-d | --dry-run | 预演模式。仅显示将要执行的操作,不会实际修改文件或停止服务。 |
-y | --yes | 自动确认。跳过所有交互式提示(如"是否继续"),直接执行。 |
-n | --no-backup | 不备份。执行升级时不创建备份文件。 |
-s | --no-stop | 不停服。执行升级时不尝试停止正在运行的服务。(不推荐,只有在确保程序已经停止的情况下使用) |
6. 核心特性详解
6.1 多实例支持
脚本原生支持多实例服务(如 crystal-call-ivr, crystal-call-phone)。
- 自动识别:能识别
startup-service1.sh这类命名的实例。 - 脚本生成:升级时,会根据基础服务的脚本模板,自动生成对应实例的启动/停止脚本,并重写内部的 JAR 文件名引用。
6.2 智能配置合并 (Smart Merge)
在更新配置文件(.conf, application.properties)时,脚本采取以下策略,防止覆盖用户的自定义配置:
- 保留现有值:如果旧配置中存在某项且值已被修改,保留旧值。
- 添加新项:如果新版本配置中包含旧版本没有的键值对,自动追加到文件中。
- 添加注释:保留新版本中的注释说明。
- 警告提示:如果某项配置在新旧版本中值不同,脚本会发出警告提示,但保留现有配置。
6.3 排除策略
为了保证服务稳定性,以下目录在备份和升级过程中通常被特殊处理:
logs/:不备份。日志文件通常体积较大且无需随程序回滚。jdk/:不更新。脚本假设 JDK 是独立安装或固定的,升级包中即使包含也不会覆盖。
6.4 版本文件处理
VERSION.txt:脚本会处理版本文件,将旧版本信息备份为带时间戳的文件,同时更新为新版本信息。
6.5 升级后启动服务
升级完成后,脚本会询问是否启动已升级的服务:
- 交互确认:默认提示
[Y/n],按回车即可启动。 - 启动验证:启动脚本执行后,脚本会轮询检查进程状态(最长等待 30 秒),确认服务是否真正启动。
- 失败诊断:如果启动失败,会输出启动脚本的错误信息(如 jar 文件缺失、Java 不可用、进程已存在等),方便快速定位问题。
- 结果汇总:启动完成后显示成功/失败数量,失败实例会列出具体名称。
- 预演模式:在
-d预演模式下,跳过启动服务询问。
7. 多实例处理机制
7.1 多实例服务识别
脚本支持以下预定义的多实例服务:
crystal-call-ivrcrystal-call-phone
7.2 多实例JAR文件处理
- 对于多实例服务,脚本会根据基础服务模板生成对应实例的JAR文件
- 升级时会先删除旧版本 jar(按实例名模糊匹配,如
crystal-call-ivr1-*.jar),再安装新版本 - JAR文件命名格式为:
<实例名>-<版本号>.jar - 例如:
crystal-call-ivr1-1.0.0.jar
7.3 多实例配置文件处理
- 主实例使用基础配置文件名(如
crystal-call-ivr.conf) - 多实例使用实例配置文件名(如
crystal-call-ivr1.conf) - 配置文件智能合并功能同样适用于多实例配置
8. 预演模式详解
使用 -d 或 --dry-run 选项时,脚本将模拟执行所有操作而不实际修改文件系统:
- 显示将要停止的服务实例
- 显示备份路径信息
- 显示将要更新的文件列表
- 显示版本更新信息
- 显示升级摘要信息
- 跳过升级后的启动服务询问
9. 注意事项
- JDK 管理:升级包中若包含 JDK,请确保其与脚本逻辑兼容,或手动处理 JDK 目录。
- Dry-run 重要性:在生产环境执行升级前,强烈建议先使用
-d(dry-run) 参数检查脚本是否识别到了正确的服务实例。 - 文件锁:如果在不停止服务的情况下 (
-s) 进行升级,可能会导致文件读写冲突,除非应用支持热更新,否则不建议使用。 - 多实例服务:对于多实例服务,确保实例命名规范,避免影响升级识别。
- VERSION.txt 文件:升级时会自动备份旧版本文件,确保版本追踪的准确性。
- 环境变量:
env.sh文件会在升级过程中更新,确保环境配置的一致性。 - 旧版本清理:升级 modules 目录时会自动删除旧版本 jar,无需手动清理。如需保留旧版本文件,请在升级前手动备份。
- 启动超时:升级后启动服务的进程检测超时为 30 秒,如果服务启动较慢,可能会被判定为启动失败。请根据服务实际启动时间合理评估。