Files
Nexus/docs/release/20260708/PR-MERGE-说明-20260709.md
T
2026-07-09 00:14:19 +08:00

363 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Nexus PR 合并说明:宝塔 Session 稳定性修复与 /app-v2 双后台
> 目标分支:`release/20260708-axs`
> 本地提交基线:`1933f0af6e647818e716ed194cdb92d7ed7bb47a`
> 编写日期:2026-07-09
> 推荐用途:复制本文件核心内容到 Gitea Pull Request 描述,用于合并评审。
## 1. 合并结论
建议合并。该分支主要解决 Nexus 的宝塔一键登录在 1~2 小时后刷新掉线的问题,同时加入 `/app-v2` 第二后台与发布制品化工具链。
本分支不是单点热修,而是一组围绕“宝塔长期登录稳定性 + 新后台并行上线 + 发布可验证”的完整改进:
- 一键登录前自动检测并修复宝塔 `task.py` 中硬编码 `3600` 秒清理 `tmp_login` session 的问题;
- 对同一台宝塔服务器的一键登录生成过程加锁,避免并发打开多个宝塔时 tmp token / session 互相覆盖;
- 新增 `/app-v2` 第二后台,保持旧后台 `/app/` 可继续使用,支持渐进替换;
- 增强发布包、发布前检查、发布验证和回滚脚本;
- 补齐代码审查、调用链、安全巡检、发布记录等文档。
## 2. 背景问题
用户实际现象:
```text
Nexus 一键登录宝塔成功
同时打开多台/多窗口宝塔
约 12 小时后刷新页面陆续掉线
```
根因链路:
```text
Nexus 一键登录成功
→ 宝塔生成 tmp_login session 文件
→ 宝塔 BT-Task 定时清理 session
→ 部分宝塔 task.py 硬编码超过 3600 秒删除 tmp_login session
→ 12 小时后刷新
→ tmp_login session 已被删除
→ 宝塔判定掉线
```
此外,同时打开多个宝塔时,同一台宝塔如果被重复触发一键登录,可能出现登录 URL / tmp token 生成冲突,因此本分支加入了分布式锁与远端 bootstrap 锁。
## 3. 本次核心改动
### 3.1 宝塔一键登录长期不掉线修复
关键能力:
- 登录前自动检测宝塔 `task.py` 是否存在 hardcoded `3600` 清理逻辑;
- 自动修复为读取 `public.get_session_timeout()`,无法读取时使用默认 `86400`
- 对新增宝塔也执行兜底检测/修复;
- 一键登录前再次兜底检测/修复,避免漏修服务器;
- 修复过程使用 SSH bootstrap,包含远端 `flock``mktemp`、atomic replace,降低并发和半写入风险;
- 同一宝塔登录 URL 生成加 Redis 分布式锁,防止同一服务器被并发打开时 token/session 互相覆盖。
重点文件:
```text
server/application/services/btpanel_service.py
server/infrastructure/btpanel/login_url_lock.py
server/infrastructure/btpanel/bootstrap_lock.py
server/infrastructure/btpanel/ssh_bootstrap.py
server/api/btpanel.py
```
相关测试:
```text
tests/test_btpanel_bootstrap_lock.py
tests/test_btpanel_get_config.py
tests/test_btpanel_login_url.py
tests/test_btpanel_login_url_route.py
tests/test_btpanel_ssh_bootstrap.py
tests/test_btpanel_temp_login_ttl.py
```
### 3.2 `/app-v2` 第二后台
新增第二后台,路径为:
```text
/app-v2/
```
设计目标:
- 不替换旧后台 `/app/`,双后台并行;
- 保留原功能入口,逐步迁移;
- 更现代、更快、更适合后续 UI 重构;
- 全局 API Key 等敏感值不直接展示真实值。
技术栈:
```text
React + TypeScript + Vite
shadcn/ui + Tailwind
TanStack Query
TanStack Table
Zustand
```
重点文件:
```text
frontend-v2/
web/app-v2/
frontend-v2/scripts/scan-app-v2-sensitive.mjs
server/main.py
Dockerfile
Dockerfile.prod
```
### 3.3 发布制品化与验证工具链
本分支加入/增强了发布包生成、扫描、元数据、发布前检查和发布辅助脚本:
```text
scripts/prepare_release_artifact.py
scripts/generate_release_bundle.py
scripts/scan_release_bundle.py
scripts/write_release_metadata.py
scripts/publish_release_bundle.py
scripts/check_text_integrity.py
scripts/generate_release_diff.py
scripts/run_local_release_gate.py
```
服务器侧脚本:
```text
deploy/preflight-release-host.sh
deploy/apply-release-bundle.sh
deploy/sync_webapp_to_container.sh
```
发布包:
```text
C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz
```
SHA256
```text
46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
```
## 4. 验证结果
本地 release gate 已通过:
```text
Python py_compile
bash -n deploy shell
部署排除规则检查
文本完整性检查
/app-v2 build:safe
app-v2 sensitive scan
宝塔专项 pytest
发布辅助脚本测试
```
测试结果:
```text
65 passed
```
发布包验证:
```text
size_mb=27.02
entries=2409
OK: release bundle looks clean
apply-release-bundle.sh --validate-only passed
metadata / .sha256 / tar 实际 SHA 一致
```
重点人工验证建议:
- `/app/` 旧后台可访问;
- `/app-v2/` 新后台可访问;
- 宝塔一键登录可打开;
- 同一台宝塔连续/并发触发一键登录不会互相覆盖;
- 新增宝塔在一键登录前会自动检测/修复 hardcoded `3600`
- 典型宝塔登录 2 小时后刷新仍保持登录状态。
## 5. 合并风险与边界
### 5.1 主要风险
1. **宝塔远端 patch 风险**
修复逻辑会通过 SSH 修改目标宝塔服务器上的 `task.py`。本项目定位中,管理员远程执行命令属于产品能力,因此这不是普通越权漏洞,但合并后需要继续保持审计日志与失败可见性。
2. **不同宝塔版本兼容性**
部分宝塔版本 `task.py` 内容可能不同。当前逻辑已经使用检测/备份/原子替换/失败回退策略,但建议继续抽检更多系统版本。
3. **双后台静态资源体积**
分支包含旧后台和新后台静态资源,仓库和发布包会变大。当前发布包约 27MB,可接受。
4. **远端批量修复节奏**
线上 420 台里曾识别出 148 台存在 hardcoded_3600。合并后建议继续采用分批检测/修复,不建议一次性对全部服务器无观察窗口地全量变更。
### 5.2 不属于本次合并要解决的问题
- 不在本次合并中重构所有后台 UI
- 不强制删除旧后台 `/app/`
- 不改变 `script_service` 管理员远程执行命令的产品定位;
- 不依赖账号密码替代宝塔 API 登录;账号密码一键登录可作为后续增强方案单独设计。
## 6. 推荐合并方式
### 6.1 推荐路径
推荐在 Gitea 上创建 Pull Request
```text
source: release/20260708-axs
target: main
```
PR 地址:
```text
https://axs.kuma1xn.vip/admin/Nexus/pulls/new/release/20260708-axs
```
建议标题:
```text
release: 宝塔 Session 长期登录修复与 /app-v2 双后台
```
建议合并策略:
```text
Create merge commit
```
理由:本分支是发布型分支,包含后端修复、前端新增、发布脚本和文档。保留 merge commit 更方便后续定位整次发布。
### 6.2 合并前检查
合并前建议在 Gitea 页面确认:
- 目标分支是 `main`
- source 分支是 `release/20260708-axs`
- 文件变更中包含 `docs/release/20260708/` 说明;
- 没有 `.venv``node_modules``.env``.pem` 等运行环境文件;
- PR 描述中粘贴本说明的第 1~8 节。
## 7. 合并后部署方式
### 7.1 仅上传 + preflight
```cmd
cd /d C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042
.venv-py312-codex\Scripts\python.exe scripts\publish_release_bundle.py ^
--remote nexus ^
--tarball C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ^
--sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b
```
### 7.2 正式 apply
preflight 无异常后再加 `--apply`
```cmd
.venv-py312-codex\Scripts\python.exe scripts\publish_release_bundle.py ^
--remote nexus ^
--tarball C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ^
--sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b ^
--apply
```
### 7.3 部署后验证
```cmd
.venv-py312-codex\Scripts\python.exe scripts\verify_online_release.py --base-url https://api.synaglobal.vip
```
期望:
```text
OK: health
OK: /app
OK: /app-v2
OK: online release verification passed
```
## 8. 回滚策略
如果合并后未部署:
```text
在 Gitea revert merge commit 即可。
```
如果已经部署:
1. 使用 `deploy/apply-release-bundle.sh` 生成的备份目录回滚;
2. 恢复上一版 `/opt/nexus` 文件;
3. 重启 Nexus 服务/容器;
4. 验证 `/health``/app/`
5. 如果问题只影响 `/app-v2/`,可临时隐藏 `/app-v2/` 路由或静态资源,不影响旧后台 `/app/`
宝塔远端 `task.py` 修复属于向更长 session timeout 的兼容性修复。若个别宝塔异常,优先按单台服务器恢复宝塔备份文件,不建议全局回滚。
## 9. 文档索引
本分支已包含详细文档,集中在:
```text
docs/release/20260708/
```
建议优先阅读:
```text
docs/release/20260708/Nexus-项目说明文档-20260708.md
docs/release/20260708/Nexus-release-index-20260708.md
docs/release/20260708/Nexus-release-ready-checklist-20260708.md
docs/release/20260708/Nexus-宝塔一键登录长期掉线修复方案与代码改进.md
docs/release/20260708/Nexus-app-v2-双后台实施说明-20260707.md
docs/release/20260708/Nexus-manual-deploy-commands-20260708.md
```
## 10. 可直接复制到 Gitea PR 的摘要
```markdown
## 合并摘要
本 PR 修复 Nexus 宝塔一键登录 1~2 小时后刷新掉线的问题,并新增 /app-v2 第二后台与发布制品化工具链。
### 核心改动
- 一键登录前自动检测/修复宝塔 task.py hardcoded 3600 清理 tmp_login session 的问题;
- 基于 public.get_session_timeout() 或默认 86400 延长 tmp_login session 有效期;
- 新增 Redis 分布式锁,避免同一宝塔并发生成登录 URL/token 互相覆盖;
- SSH bootstrap 使用 flock / mktemp / atomic replace 降低远端 patch 风险;
- 新增 /app-v2 第二后台,旧后台 /app/ 保留;
- 增强发布包生成、扫描、preflight、validate-only、apply 与回滚脚本;
- 补齐发布说明、调用链、安全巡检、宝塔修复记录等文档。
### 验证
- release gate 通过;
- 宝塔专项测试通过;
- 发布辅助脚本测试通过;
- 合计 65 passed
- 发布包扫描通过;
- apply-release-bundle.sh --validate-only 通过;
- 发布包 SHA256: 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b。
### 风险
- 会通过 SSH 对目标宝塔服务器 task.py 做自动修复,已加入检测、备份、锁和原子替换;
- /app-v2 与 /app 双后台并行,不删除旧后台;
- 建议合并后先 preflight,再 apply,并对宝塔一键登录做 2 小时刷新验证。
```