# 升级后卡在「重启服务」怎么办（1.1.20 已修复）

> 如果你在升级时遇到过这两个现象，本文说明原因与解决办法。
> **1.1.20 已彻底修复，升级到该版本后不会再出现。**

## 现象

1. 后台点「一键升级」，升到最后一步时**突然被踢出后台**（跳回登录页）
2. 重新登录后，进度**永远停在「重启服务」**，一直转圈不结束
3. 刷新页面也没用，任务列表里那条记录永远是「进行中」

## 原因

这两个现象是同一个流程里的两处死角：

### 一、为什么会被踢出后台

升级的最后一步是**重启服务**（`pm2 reload`）。这个操作会**把服务进程整个换掉**。

而旧版本把管理员的登录凭据存在**服务进程的内存里**。进程一换，内存清空 —— 你的登录态就没了。

> 打个比方：钥匙存在门卫的口袋里，门卫一换班，钥匙就找不到了。

### 二、为什么一直卡在「重启服务」

`pm2 reload` 的工作方式是「**先起新进程、再退旧进程**」。

升级任务的收尾代码（健康检查 + 标记完成）原本跑在**旧的进程**里，
但旧进程恰好**死在「重启服务」这一步**，那段收尾代码就永远没机会执行。

于是磁盘上的任务记录一直写着「进行中」，新进程起来后也**不知道要去接手**，
前端就只好永远转圈。

> 打个比方：交接班时上一班的同事没填完交接单就走了，下一班不知道有这回事。

## 解决办法（任选其一）

### 方案 A：升级到 1.1.20（推荐）

下载新的全量升级包，上传到 `upgrade/incoming/`，在后台执行升级即可。
本次升级完成后：

- **不会**再被踢出后台（登录态改为签名凭据，重启后依然有效）
- **不会**再卡住（新进程启动时会自动接手并收尾未完成的任务）
- 重启那十几秒，页面会提示「正在重启服务…页面会自动恢复，无需重新登录」

### 方案 B：如果你现在就卡住了（尚未升级到 1.1.20）

**先确认服务其实已经恢复正常**，只是那条任务记录没被标记完成：

1. 直接刷新页面 / 重新打开后台地址，**重新登录**
2. 到「系统升级」页看**当前版本号**：
   - 如果已经是**目标版本**（比如从 1.1.13 升到 1.1.16，现在显示 1.1.16）→ **说明升级其实成功了**，只是记录没标完，可以放心使用
   - 如果还是旧版本 → 说明升级确实没做完，**重新执行一次升级**即可（系统会自动备份、失败自动回滚，可放心重试）

3. 那条永远「进行中」的旧记录是这次意外留下的，**升级到 1.1.20 后不会再产生**，历史记录可以直接忽略

## 如何确认已经修好

升级到 **1.1.20** 后，做一次升级时会看到：

- 重构进度条走到最后一步「重启服务」时，页面显示
  **「⏳ 正在重启服务…页面会自动恢复，无需重新登录」**
- 等十几秒，页面**自动**恢复，进度条走完，弹出「升级完成」
- **全程不需要重新登录**

## 技术细节（给运维同学）

| 项目 | 旧实现 | 1.1.20 |
|---|---|---|
| 登录凭据 | 进程内存中的 `Set` | 自包含 HMAC 签名 token（密钥持久在 `data/secret.key`，默认 7 天） |
| 登出吊销 | 从内存 `Set` 删除 | `jti` 黑名单精确吊销 |
| 越权防护 | — | 校验 `scope=admin`，普通用户 token 无法用于后台 |
| 重启后任务收尾 | 无（任务永远 `running`） | 新进程启动时扫描磁盘未完成任务并续接 |

续接的判定是**保守**的，只在确凿可判成功时才判成功：

- 已走到「重启服务」步骤 **且** 文件替换、版本锚点均已完成 → 补做健康检查后判 **成功**
- 还在中途（未到重启步骤）→ **原样保留**，不误判成功也不误判失败，留待人工确认
- 已到重启步骤但文件未就位（状态矛盾）→ 明确判 **失败** 并提示重新执行，绝不掩盖问题

续接**只处理升级任务**，不会误碰发布任务；且是**幂等**的，重复启动不会重复处理。

### 人工核对命令

```bash
# 进入站点目录
cd /www/wwwroot/你的域名/

# 查看当前版本
cat package.json | grep '"version"'

# 查看升级任务日志（status 应该是 success）
ls upgrade/logs/
cat upgrade/logs/<最新的任务id>.json | head -20

# 重启服务
pm2 restart avc
```
