feat: automate business upgrades and sync reviewed frontend
This commit is contained in:
+20
-13
@@ -15,23 +15,30 @@
|
||||
- 后端仅绑定 `127.0.0.1:9602`,前端仅绑定 `127.0.0.1:9601`。
|
||||
- 宝塔 `sw2.fuhua91.com` 代理至 9601,前端容器将 `/api/` 转发至后端并去除前缀,支持 WebSocket、SSE 和文件上传。
|
||||
|
||||
数据库沿用已迁移并验证的 `sw10`,设置 `admin.system.disable_auto_migrate: true`,由部署前的独立迁移命令更新结构。平台别名为 `lx/hw/yq/oa`,其中三个 SDK 别名连接 `game_lx/game_hw/game_yq` 测试库,Redis 沿用当前关闭状态。生产配置使用 `admin.app.env: production`,关闭开发 Swagger。七条常规任务启用(四条商务/区服日汇总、预警检测、两条有效端刷新),两个历史回填停用。**使用同一 sw10 时只运行一个调度实例,切换到服务器前停止本机的后端服务。**
|
||||
测试数据库为 `sw10`。程序和部署入口会自动识别旧商务库并完成整套升级;已有 `disable_auto_migrate` 配置不会跳过商务升级。平台别名为 `lx/hw/yq/oa`,其中三个 SDK 别名连接 `game_lx/game_hw/game_yq` 测试库,Redis 沿用当前关闭状态。生产配置使用 `admin.app.env: production`,关闭开发 Swagger。七条常规任务启用(四条商务/区服日汇总、预警检测、两条有效端刷新),两个历史回填停用。**使用同一 sw10 时只运行一个调度实例,切换到服务器前停止本机的后端服务。**
|
||||
|
||||
## 数据库迁移
|
||||
## 全自动数据库升级
|
||||
|
||||
新副本必须先完整复制旧商务数据库,再执行 [旧框架转换 SQL](../migrations/legacy-framework.sql),最后使用本次发布的后端执行全部增量迁移:
|
||||
将主数据库配置为准备接管的旧商务库,然后正常部署或启动程序即可。程序不创建空库替代旧数据,不需要手动运行 SQL、建立索引、回填角色映射或执行旧表清理。部署脚本中的 `-migrate` 与直接启动后端使用同一条自动流程。
|
||||
|
||||
执行顺序:识别旧库并取得迁移锁 → 备份受影响的数据 → 转换旧框架 → 执行全部增量迁移和索引 → 校验结构、数据记录和商务角色 → 备份待清理表 → 删除明确名单中的旧表 → 再次校验 → 开放业务接口及调度任务。首次接管前,旧程序应处于正常发布停写状态;检测到迁移期间账号发生变化时会停止清理。
|
||||
|
||||
阶段进度、失败原因、备份摘要和完成时间记录在 `sys_business_upgrade_state`,迁移版本仍记录在 `sys_schema_migrations`。同库的多个新实例会等待同一把锁。建索引不设置总超时,日志每 10 秒报告当前阶段;在全部步骤完成前,业务服务不会就绪。
|
||||
|
||||
备份自动写入配置文件旁的 `migration-backups/`,在当前 Docker 部署中对应 `/www/wwwroot/sw2.fuhua91.com/config/migration-backups/`。目录权限为 700、文件为 600,不对外提供下载。备份包含受转换影响的系统数据、待删除旧表及其结构;只新增索引的原始业务大表保留在原库,其旧结构以注释写入备份。渠道主键扩容涉及的 `tab_promote` 同时备份数据。备份完整写入并校验 SHA-256 后才允许清理,历史备份不会随容器替换删除。
|
||||
|
||||
旧角色映射会一次性回填到 `sys_authorities.business_level`,之后创建商务账号只按稳定的等级标识查角色。角色可改名,复制角色不复制该标识,内置商务角色禁止删除。旧用户 ID、角色 ID、权限关联及主键自增高水位保持迁移约定,不因移除映射表再次编号。
|
||||
|
||||
当前自动清理名单为 79 张:19 张旧框架归档、26 张迁移前备份、23 张旧 SnailJob 表、4 张旧代码生成/演示表、2 张旧预警去重备份,以及 5 张已归档的 `sw_kra_*` 迁移辅助表。正常业务表和两个必要的迁移状态表保留;原 156 表的已迁移库升级后为 78 表。初次迁移时沿用旧任务启停状态,已运行的新商务库则保持现有任务设置。
|
||||
|
||||
发生中断后,重新启动或重新部署会根据持久化状态继续:尚未提交数据的旧框架转换可重新创建空目标结构,已提交的数据不会再次映射 ID,已有索引会校验后跳过,部分完成的清理使用原来的完整备份继续。验证失败、备份损坏或发现外键/视图等依赖时保留原表并报告原因。数据库已改变时,部署脚本只在旧版本通过结构检查后才允许回退到旧镜像。
|
||||
|
||||
[框架转换 SQL](../migrations/legacy-framework.sql) 与 [清理 SQL](../migrations/cleanup-legacy.sql) 是程序内嵌的执行内容,供审阅和应急排查,正常部署无需手工调用。可选的只读诊断命令:
|
||||
|
||||
```bash
|
||||
/app/kratos-admin -conf /data/conf/config.yaml -migrate
|
||||
/app/kratos-admin -conf /data/conf/config.yaml -check-schema
|
||||
```
|
||||
|
||||
框架转换 SQL 的 `USE` 默认指向 sw10,其他目标库需修改该行。`-migrate` 使用与服务相同的模块迁移目录,包含新表、字段、索引、权限及任务定义,完成检查后退出;不会启动 HTTP、定时任务或 SDK 连接。`-check-schema` 只读检查版本、必需表和字段、主键与索引。旧业务表缺失时应重新完成复制,不能用空表替代历史数据。
|
||||
|
||||
转换 SQL 和增量迁移必须全部执行。服务关闭自动迁移后,会在连接失败、版本未完成或结构缺失时明确报错,不进入初始化向导。新增迁移需同时更新模块结构检查与相邻回归测试。部署脚本在停止旧调度实例后自动运行 `-migrate`,全部检查通过才启动新服务。
|
||||
|
||||
旧库 `tab_promote.id` 的 INT 自增容量由增量迁移扩大为同符号 BIGINT,保留现存 ID、自增高水位、关联数据与注释。渠道、玩家、流水等可能变大的旧业务 ID 在 JSON 和 Excel 中使用文本,请求兼容十进制字符串;不降低自增值或重新编号。
|
||||
|
||||
## 构建与发布
|
||||
|
||||
Windows 本机安装 Go、Node、pnpm、tar,先提交源代码,再执行:
|
||||
@@ -42,7 +49,7 @@ Windows 本机安装 Go、Node、pnpm、tar,先提交源代码,再执行:
|
||||
|
||||
输出位于 `.cache/deploy/sw2-<commit>.tar.gz` 及对应 SHA-256 文件。后端交叉编译为 Linux amd64,前端执行生产构建;包内只含二进制、前端产物、Dockerfile 和部署配置,真实运行配置及环境变量不进入镜像或 Git。
|
||||
|
||||
通过 SSH 将包上传到 226,校验 SHA-256 后解压到 `releases/<commit>/`。首次部署另行准备上述私有配置文件,保持 `admin.router_prefix` 为空,并确认主库为 sw10。SDK 环境变量名称为 `SW_SDK_AUTH_CODE`、`SW_SDK_MIGRATE_AUTH_CODE`、`SW_SDK_TABLE_PREFIX`,值从已有私有运行配置取得。
|
||||
通过 SSH 将包上传到 226,校验 SHA-256 后解压到 `releases/<commit>/`。首次部署准备上述私有配置文件,保持 `admin.router_prefix` 为空,主库填写待接管的旧商务数据库。SDK 环境变量名称为 `SW_SDK_AUTH_CODE`、`SW_SDK_MIGRATE_AUTH_CODE`、`SW_SDK_TABLE_PREFIX`,值从已有私有运行配置取得。
|
||||
|
||||
```bash
|
||||
bash /www/wwwroot/sw2.fuhua91.com/releases/<commit>/deploy.sh <commit> --build-only
|
||||
@@ -50,9 +57,9 @@ bash /www/wwwroot/sw2.fuhua91.com/releases/<commit>/deploy.sh <commit> --build-o
|
||||
bash /www/wwwroot/sw2.fuhua91.com/releases/<commit>/deploy.sh <commit>
|
||||
```
|
||||
|
||||
脚本先构建和检查镜像,再停止当前受管容器,保留一份停止的 `-previous` 容器。迁移或健康检查失败时恢复前一组容器。配置、上传文件和数据库不随镜像替换;索引在独立迁移容器中按版本执行。
|
||||
脚本先构建和检查镜像,再停止当前受管容器,保留一份停止的 `-previous` 容器。迁移或健康检查失败时,先检查旧版本是否兼容当前数据库,再决定是否恢复前一组容器。配置、备份和上传文件不随镜像替换;完整数据库升级在独立迁移容器中自动执行。
|
||||
|
||||
迁移不设置总等待时限,日志记录每一步的名称、结果和耗时;耗时索引完成前不会启动业务服务。业务容器退出或重启时立即回退。切换数据库前需备份运行配置;镜像回退不会自动还原数据库连接配置或撤销已执行的数据库迁移,回退版本需兼容当前结构和迁移版本。
|
||||
迁移不设置总等待时限,日志记录每一步的名称、结果和耗时;耗时索引完成前不会启动业务服务。业务容器退出或重启时进入兼容性检查后再处理回退。切换数据库前需备份运行配置;镜像回退不会自动还原数据库连接配置或撤销已执行的数据库迁移,回退版本需兼容当前结构和迁移版本。
|
||||
|
||||
首次接入域名时,备份宝塔原站点配置,再安装 `bt-nginx-sw2.fuhua91.com.conf` 至 `/www/server/panel/vhost/nginx/`,执行 `/www/server/nginx/sbin/nginx -t` 通过后重载。模板保留证书验证目录,当前监听 HTTP;后续由宝塔为 sw2 单独配置匹配域名的证书。
|
||||
|
||||
|
||||
@@ -47,7 +47,11 @@ try {
|
||||
foreach ($name in @('deploy.sh', 'wait-backend.sh', 'bt-nginx-sw2.fuhua91.com.conf')) {
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot $name) -Destination (Join-Path $stage $name)
|
||||
}
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot '..\migrations') -Destination (Join-Path $stage 'migrations') -Recurse
|
||||
$migrationOutput = Join-Path $stage 'migrations'
|
||||
New-Item -ItemType Directory -Force -Path $migrationOutput | Out-Null
|
||||
Get-ChildItem -LiteralPath (Join-Path $PSScriptRoot '..\migrations') -Filter '*.sql' -File | ForEach-Object {
|
||||
Copy-Item -LiteralPath $_.FullName -Destination $migrationOutput
|
||||
}
|
||||
& tar -czf $archive -C $stage .
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Release archive failed' }
|
||||
$hash = (Get-FileHash -LiteralPath $archive -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
|
||||
+13
-2
@@ -73,6 +73,17 @@ rollback() {
|
||||
result=$?
|
||||
trap - ERR
|
||||
set +eu
|
||||
# A successful schema/data upgrade cannot be undone by switching images.
|
||||
# Probe the old binary before letting it touch the upgraded database.
|
||||
if exists sw2-backend-previous; then
|
||||
previous_image=$(docker inspect --format '{{.Config.Image}}' sw2-backend-previous)
|
||||
if ! docker run --rm --network "$NETWORK" --env-file "$BASE_DIR/runtime.env" \
|
||||
-v "$BASE_DIR/config:/data/conf:ro" -v "$BASE_DIR/log:/app/logs" \
|
||||
"$previous_image" /app/kratos-admin -conf /data/conf/config.yaml -check-schema; then
|
||||
echo 'Deployment failed after a database change. Upgrade state/backups and current containers are retained; the incompatible previous backend stays stopped. Redeploying resumes the database upgrade.' >&2
|
||||
exit "$result"
|
||||
fi
|
||||
fi
|
||||
for name in "${created[@]}"; do docker rm -f "$name" >/dev/null 2>&1; done
|
||||
for name in "${moved[@]}"; do
|
||||
if exists "$name-previous"; then docker rename "$name-previous" "$name"; fi
|
||||
@@ -91,10 +102,10 @@ for name in "${NAMES[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
echo 'Applying and verifying database migrations before starting the service.'
|
||||
echo 'Automatically converting, migrating, verifying and cleaning the business database before starting the service.'
|
||||
docker run --rm --name sw2-migrate --label com.sw2.application=sw2 \
|
||||
--network "$NETWORK" --env-file "$BASE_DIR/runtime.env" \
|
||||
-v "$BASE_DIR/config:/data/conf:ro" -v "$BASE_DIR/log:/app/logs" \
|
||||
-v "$BASE_DIR/config:/data/conf" -v "$BASE_DIR/log:/app/logs" \
|
||||
"$BACKEND_IMAGE" /app/kratos-admin -conf /data/conf/config.yaml -migrate
|
||||
|
||||
created+=(sw2-backend)
|
||||
|
||||
Reference in New Issue
Block a user