300 lines
6.3 KiB
Markdown
300 lines
6.3 KiB
Markdown
|
|
# Redis数据结构文档
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
本文档详细说明了BLS Project Console中使用的Redis数据结构,包括新的统一项目列表结构和旧结构的迁移方案。
|
|||
|
|
|
|||
|
|
## 数据结构
|
|||
|
|
|
|||
|
|
### 1. 项目心跳列表(新结构)
|
|||
|
|
|
|||
|
|
**键名**: `项目心跳`
|
|||
|
|
|
|||
|
|
**类型**: String (JSON数组)
|
|||
|
|
|
|||
|
|
**描述**: 统一存储所有项目的心跳信息,替代原有的分散键结构。
|
|||
|
|
|
|||
|
|
**数据格式**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
[
|
|||
|
|
{
|
|||
|
|
"projectName": "string",
|
|||
|
|
"apiBaseUrl": "string",
|
|||
|
|
"lastActiveAt": "number"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**字段说明**:
|
|||
|
|
|
|||
|
|
- `projectName`: 项目名称(字符串)
|
|||
|
|
- `apiBaseUrl`: 项目API基础URL(字符串),对应“API地址”
|
|||
|
|
- `lastActiveAt`: 最新心跳时间(Unix 时间戳毫秒,数字),对应“最新心跳时间”
|
|||
|
|
|
|||
|
|
**与需求字段对应**:
|
|||
|
|
|
|||
|
|
- 项目名称 → `projectName`
|
|||
|
|
- API地址 → `apiBaseUrl`
|
|||
|
|
- 最新心跳时间 → `lastActiveAt`
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
[
|
|||
|
|
{
|
|||
|
|
"projectName": "用户管理系统",
|
|||
|
|
"apiBaseUrl": "http://localhost:8080",
|
|||
|
|
"lastActiveAt": 1704067200000
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"projectName": "数据可视化平台",
|
|||
|
|
"apiBaseUrl": "http://localhost:8081",
|
|||
|
|
"lastActiveAt": 1704067260000
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 项目控制台日志
|
|||
|
|
|
|||
|
|
**键名**: `{projectName}_项目控制台`
|
|||
|
|
|
|||
|
|
**类型**: List
|
|||
|
|
|
|||
|
|
**描述**: 存储项目的日志记录,使用Redis列表结构实现日志队列。
|
|||
|
|
|
|||
|
|
**数据格式**: 每个列表元素是一个JSON字符串,包含日志信息。
|
|||
|
|
|
|||
|
|
**日志对象格式**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"id": "string",
|
|||
|
|
"timestamp": "ISO-8601 string",
|
|||
|
|
"level": "string",
|
|||
|
|
"message": "string",
|
|||
|
|
"metadata": "object (optional)"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**字段说明**:
|
|||
|
|
|
|||
|
|
- `id`: 日志唯一标识符
|
|||
|
|
- `timestamp`: ISO-8601格式的时间戳
|
|||
|
|
- `level`: 日志级别(info, warn, error, debug)
|
|||
|
|
- `message`: 日志消息内容
|
|||
|
|
- `metadata`: 可选的附加元数据
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"id": "log-1704067200000-abc123",
|
|||
|
|
"timestamp": "2024-01-01T00:00:00.000Z",
|
|||
|
|
"level": "info",
|
|||
|
|
"message": "系统启动成功",
|
|||
|
|
"metadata": {
|
|||
|
|
"version": "1.0.0",
|
|||
|
|
"environment": "production"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 项目控制指令
|
|||
|
|
|
|||
|
|
**键名**: `{projectName}_控制`
|
|||
|
|
|
|||
|
|
**类型**: List
|
|||
|
|
|
|||
|
|
**描述**: 存储发送给项目的控制指令。
|
|||
|
|
|
|||
|
|
**指令对象格式**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"commandId": "string",
|
|||
|
|
"timestamp": "ISO-8601 string",
|
|||
|
|
"source": "string",
|
|||
|
|
"apiName": "string",
|
|||
|
|
"args": "array",
|
|||
|
|
"argsText": "string",
|
|||
|
|
"extraArgs": "object (optional)"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**字段说明**:
|
|||
|
|
|
|||
|
|
- `commandId`: 指令唯一标识符
|
|||
|
|
- `timestamp`: ISO-8601格式的时间戳
|
|||
|
|
- `source`: 指令来源(如"BLS Project Console")
|
|||
|
|
- `apiName`: 目标API接口名称
|
|||
|
|
- `args`: 指令参数数组
|
|||
|
|
- `argsText`: 指令参数文本
|
|||
|
|
- `extraArgs`: 可选的额外参数
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"commandId": "cmd-1704067200000-xyz789",
|
|||
|
|
"timestamp": "2024-01-01T00:00:00.000Z",
|
|||
|
|
"source": "BLS Project Console",
|
|||
|
|
"apiName": "/api/reload",
|
|||
|
|
"args": ["config"],
|
|||
|
|
"argsText": "config",
|
|||
|
|
"extraArgs": {
|
|||
|
|
"force": true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 项目心跳(旧结构,已废弃)
|
|||
|
|
|
|||
|
|
**键名**: `{projectName}_项目心跳`
|
|||
|
|
|
|||
|
|
**类型**: String (JSON对象)
|
|||
|
|
|
|||
|
|
**描述**: 旧的项目心跳数据结构,已迁移到统一的项目列表结构。
|
|||
|
|
|
|||
|
|
**注意**: 此结构已废弃,仅用于向后兼容。新项目应使用统一的`项目心跳`列表结构。
|
|||
|
|
|
|||
|
|
## 数据迁移
|
|||
|
|
|
|||
|
|
### 迁移工具
|
|||
|
|
|
|||
|
|
位置: `src/backend/services/migrateHeartbeatData.js`
|
|||
|
|
|
|||
|
|
### 迁移步骤
|
|||
|
|
|
|||
|
|
1. **准备阶段**
|
|||
|
|
- 确保Redis服务正常运行
|
|||
|
|
- 备份现有数据(可选)
|
|||
|
|
|
|||
|
|
2. **执行迁移**
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
import { migrateHeartbeatData } from './services/migrateHeartbeatData.js';
|
|||
|
|
|
|||
|
|
// 干运行模式(不实际写入数据)
|
|||
|
|
await migrateHeartbeatData({ dryRun: true });
|
|||
|
|
|
|||
|
|
// 实际迁移
|
|||
|
|
await migrateHeartbeatData({ deleteOldKeys: false });
|
|||
|
|
|
|||
|
|
// 迁移并删除旧键
|
|||
|
|
await migrateHeartbeatData({ deleteOldKeys: true });
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **验证迁移**
|
|||
|
|
- 检查`项目心跳`键是否包含所有项目
|
|||
|
|
- 验证每个项目的数据完整性
|
|||
|
|
- 测试项目选择和日志功能
|
|||
|
|
|
|||
|
|
### 迁移API
|
|||
|
|
|
|||
|
|
**端点**: `POST /api/projects/migrate`
|
|||
|
|
|
|||
|
|
**请求体**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"deleteOldKeys": false,
|
|||
|
|
"dryRun": false
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**参数说明**:
|
|||
|
|
|
|||
|
|
- `deleteOldKeys`: 是否删除旧的心跳键(默认: false)
|
|||
|
|
- `dryRun`: 是否为干运行模式(默认: false)
|
|||
|
|
|
|||
|
|
**响应**:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"message": "数据迁移完成",
|
|||
|
|
"migrated": 2,
|
|||
|
|
"projects": [...],
|
|||
|
|
"listKey": "项目心跳",
|
|||
|
|
"deleteOldKeys": false
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 向后兼容性
|
|||
|
|
|
|||
|
|
为确保平滑过渡,系统在读取项目心跳时采用以下策略:
|
|||
|
|
|
|||
|
|
1. **优先读取新结构**: 首先尝试从`项目心跳`列表中查找项目
|
|||
|
|
2. **回退到旧结构**: 如果新结构中未找到,则尝试从`{projectName}_项目心跳`键中读取
|
|||
|
|
3. **自动迁移**: 当检测到旧结构数据时,可以自动迁移到新结构
|
|||
|
|
|
|||
|
|
## 性能优化
|
|||
|
|
|
|||
|
|
### 1. 项目列表查询
|
|||
|
|
|
|||
|
|
- 使用单一键存储所有项目,减少Redis查询次数
|
|||
|
|
- 支持一次性获取所有项目信息
|
|||
|
|
|
|||
|
|
### 2. 日志轮询
|
|||
|
|
|
|||
|
|
- 使用Redis列表的`lRange`命令高效获取最新日志
|
|||
|
|
- 支持限制返回的日志数量
|
|||
|
|
|
|||
|
|
### 3. 心跳更新
|
|||
|
|
|
|||
|
|
- 直接更新项目列表中的对应项目
|
|||
|
|
- 避免频繁的键操作
|
|||
|
|
|
|||
|
|
## 监控和维护
|
|||
|
|
|
|||
|
|
### 健康检查
|
|||
|
|
|
|||
|
|
定期检查以下指标:
|
|||
|
|
|
|||
|
|
- Redis连接状态
|
|||
|
|
- 项目列表完整性
|
|||
|
|
- 日志队列长度
|
|||
|
|
|
|||
|
|
### 清理策略
|
|||
|
|
|
|||
|
|
- 定期清理过期的日志记录
|
|||
|
|
- 移除长时间未活跃的项目
|
|||
|
|
- 清理已废弃的旧键
|
|||
|
|
|
|||
|
|
## 安全考虑
|
|||
|
|
|
|||
|
|
1. **访问控制**: 确保只有授权的应用可以写入心跳数据
|
|||
|
|
2. **数据验证**: 验证心跳数据的格式和内容
|
|||
|
|
3. **速率限制**: 限制心跳更新频率,防止滥用
|
|||
|
|
|
|||
|
|
## 故障排查
|
|||
|
|
|
|||
|
|
### 常见问题
|
|||
|
|
|
|||
|
|
1. **项目列表为空**
|
|||
|
|
- 检查Redis连接
|
|||
|
|
- 验证`项目心跳`键是否存在
|
|||
|
|
- 检查数据格式是否正确
|
|||
|
|
|
|||
|
|
2. **日志不显示**
|
|||
|
|
- 确认项目名称正确
|
|||
|
|
- 检查`{projectName}_项目控制台`键是否存在
|
|||
|
|
- 验证日志数据格式
|
|||
|
|
|
|||
|
|
3. **命令发送失败**
|
|||
|
|
- 检查项目是否在线
|
|||
|
|
- 验证API地址是否正确
|
|||
|
|
- 确认目标项目是否正常运行
|
|||
|
|
|
|||
|
|
## 版本历史
|
|||
|
|
|
|||
|
|
- **v2.0** (2024-01-13): 引入统一的项目列表结构
|
|||
|
|
- **v1.0** (初始版本): 使用分散的项目心跳键
|
|||
|
|
|
|||
|
|
## 参考资料
|
|||
|
|
|
|||
|
|
- [Redis数据类型](https://redis.io/docs/data-types/)
|
|||
|
|
- [项目OpenSpec规范](../openspec/specs/)
|
|||
|
|
- [API文档](../docs/api-documentation.md)
|