docs: 账户状态响应
This commit is contained in:
parent
112d3907be
commit
cf12f6e37e
162
docs/账号状态实时响应技术方案.md
Normal file
162
docs/账号状态实时响应技术方案.md
Normal file
@ -0,0 +1,162 @@
|
||||
# 账号状态实时响应技术方案
|
||||
|
||||
## 背景需求
|
||||
|
||||
当管理员对用户账号进行冻结/封禁操作时,需要立即将当前在线用户的登录状态强制退出,保障平台安全。
|
||||
|
||||
---
|
||||
|
||||
## 方案一:WebSocket 实时推送
|
||||
|
||||
### 核心原理
|
||||
|
||||
服务端与客户端建立 TCP 长连接,当账号状态发生变化时,服务端主动通过 WebSocket 通道推送踢人指令,客户端收到后立即跳转登录页。
|
||||
|
||||
### 核心技术点
|
||||
|
||||
| 技术点 | 说明 |
|
||||
|--------|------|
|
||||
| **连接管理** | 服务端维护所有在线用户的 WebSocket 连接,使用 Map<userID, Connection> 管理 |
|
||||
| **心跳机制** | 客户端每 30s 发送心跳,服务端检测存活,断线时移除连接 |
|
||||
| **断线重连** | 客户端检测到断连后,采用指数退避策略重连(1s、2s、4s...最大 30s) |
|
||||
| **消息协议** | 推送消息格式 `{type: "KICK_OUT", reason: "账号已被封禁", timestamp: 123456789}` |
|
||||
| **多端同步** | 一个用户可能在手机、平板多端登录,需同时向所有连接推送 |
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
管理员操作 → 更新账号状态 → 消息队列 → WebSocket服务 → 推送至所有在线连接 → 客户端跳转登录页
|
||||
```
|
||||
|
||||
### 优缺点
|
||||
|
||||
- ✅ 实时性最强(毫秒级)
|
||||
- ✅ 支持主动推送,可扩展系统通知等场景
|
||||
- ❌ 需要维护长连接池,增加运维复杂度
|
||||
- ❌ 移动端电量消耗较高
|
||||
- ❌ 弱网络环境下可能延迟不稳定
|
||||
|
||||
---
|
||||
|
||||
## 方案二:轮询检测
|
||||
|
||||
### 核心原理
|
||||
|
||||
客户端定期(如每 60 秒)调用账号状态查询接口,服务端返回当前账号状态,客户端根据返回值决定是否踢出用户。
|
||||
|
||||
### 核心技术点
|
||||
|
||||
| 技术点 | 说明 |
|
||||
|--------|------|
|
||||
| **轮询间隔** | 建议 60 秒,平衡实时性与服务器压力 |
|
||||
| **请求优化** | 使用 `Last-Modified` / `ETag` 协商缓存,无变化时服务端返回 304 |
|
||||
| **静默检测** | 检测在后台静默进行,不阻塞用户操作,不打断交互 |
|
||||
| **差异化策略** | 新用户/高风险用户缩短轮询间隔,老用户/低风险用户延长间隔 |
|
||||
| **错误处理** | 网络异常时继续轮询,不因单次失败终止 |
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
客户端定时器(60s) → 查询账号状态API → 返回status →
|
||||
├─ status == "normal" → 继续使用
|
||||
└─ status == "frozen/banned" → 跳转登录页 + 显示原因
|
||||
```
|
||||
|
||||
### 优缺点
|
||||
|
||||
- ✅ 实现简单,无需额外基础设施
|
||||
- ✅ 可复用现有接口,改动小
|
||||
- ✅ 调试方便,日志清晰
|
||||
- ❌ 存在延迟,最多等待一个轮询周期
|
||||
- ❌ 大规模用户时请求量较高
|
||||
- ❌ 客户端电量消耗
|
||||
|
||||
---
|
||||
|
||||
## 方案三:JWT Token 黑名单
|
||||
|
||||
### 核心原理
|
||||
|
||||
当账号被封禁时,将该用户的 Token 加入黑名单,后续每次请求网关校验 Token 时检查黑名单,发现则返回 401 强制登出。
|
||||
|
||||
### 核心技术点
|
||||
|
||||
| 技术点 | 说明 |
|
||||
|--------|------|
|
||||
| **存储选型** | 使用 Redis Set 存储黑名单 Token,O(1) 查询效率 |
|
||||
| **Key 设计** | `blacklist:{userID}` 或 `blacklist:{tokenSignature}` |
|
||||
| **过期策略** | Token 本身有过期时间,黑名单设置相同 TTL,自动清理 |
|
||||
| **网关校验** | 在 JWT 校验层增加黑名单检查逻辑,位于 Token 验证之后 |
|
||||
| **性能优化** | 本地缓存热点用户黑名单,减少 Redis 请求 |
|
||||
| **批量封禁** | 管理员操作后可批量写入黑名单,减少数据库操作 |
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
管理员封禁 → 写入Redis黑名单 → 用户请求 →
|
||||
→ 网关校验JWT → 检查黑名单 →
|
||||
├─ 不在黑名单 → 继续处理请求
|
||||
└─ 在黑名单 → 返回401 + 跳转登录页
|
||||
```
|
||||
|
||||
### 优缺点
|
||||
|
||||
- ✅ 无需客户端配合,服务端完全可控
|
||||
- ✅ 分布式友好,多实例共享黑名单
|
||||
- ✅ 安全性高,Token 失效立即生效
|
||||
- ❌ 无法主动通知用户"为什么被封"
|
||||
- ❌ 需要引入 Redis 依赖
|
||||
|
||||
---
|
||||
|
||||
## 推荐方案:轮询 + JWT 黑名单组合
|
||||
|
||||
### 组合策略
|
||||
|
||||
| 场景 | 处理方式 | 实时性 |
|
||||
|------|---------|--------|
|
||||
| **登录时** | 检测账号状态,异常拒绝登录 | 即时 |
|
||||
| **登录后静默检测** | 每 60 秒轮询账号状态 | ≤60秒 |
|
||||
| **被封禁后** | Token 加入黑名单,下次请求时拦截 | 即时 |
|
||||
| **Token 校验** | 网关层检查黑名单 | 即时 |
|
||||
|
||||
### 为什么组合使用
|
||||
|
||||
1. **轮询**解决"不知道为什么被封"的问题,用户下次操作时能拿到具体原因
|
||||
2. **黑名单**解决"Token 仍然有效"的问题,被封用户即使不轮询,请求也会被拦截
|
||||
3. 两者互补,覆盖所有边界场景
|
||||
|
||||
### 延迟分析
|
||||
|
||||
| 操作 | 响应时间 |
|
||||
|------|---------|
|
||||
| 管理员封禁 → 请求被拦截 | < 1秒(下次请求) |
|
||||
| 管理员封禁 → 前端感知 | < 60秒(轮询周期) |
|
||||
|
||||
### 后续扩展
|
||||
|
||||
如平台后续需要更多实时通知(如系统公告、消息提醒),可在组合方案基础上引入 WebSocket,不会浪费已有投资。
|
||||
|
||||
---
|
||||
|
||||
## 附录:数据库表结构参考
|
||||
|
||||
```sql
|
||||
-- 账号状态表
|
||||
CREATE TABLE user_account_status (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL UNIQUE,
|
||||
status VARCHAR(20) NOT NULL, -- normal/frozen/banned
|
||||
reason TEXT, -- 冻结/封号原因
|
||||
frozen_until BIGINT, -- 冻结解封时间戳(毫秒)
|
||||
operator_id BIGINT, -- 操作人ID
|
||||
operated_at BIGINT, -- 操作时间
|
||||
created_at BIGINT NOT NULL,
|
||||
updated_at BIGINT NOT NULL
|
||||
);
|
||||
|
||||
-- Redis 黑名单Key设计
|
||||
-- Key: blacklist:user:{userID}
|
||||
-- Value: 1
|
||||
-- TTL: 与Token过期时间一致
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user