feat(server,dashboard): 引入多工作流数据隔离、安全中间件与前端 ESM 模块化重构
- server: 实现按 workflow_name 的多工作流数据隔离与旧数据库平滑迁移机制 - server: 新增 API Key 认证(auth)、限流中间件(rate_limit)与运维备份接口(admin) - server: 统一 AppError 错误处理体系,重构调度器 scheduler 支持工作流级重置与抢占 - node: 节点 ID 缺失时自动生成随机 UUID,原生支持 `docker compose --scale node=N` 动态扩容 - dashboard: 前端模块化重构(state/api/components),升级 CSS 变量设计系统与 Toast 通知 - docker/docs: 更新 /healthz 健康检查、部署脚本 IP 配置及数据库设计文档
This commit is contained in:
+83
-15
@@ -25,26 +25,36 @@
|
||||
- **传输协议**: HTTP / HTTPS
|
||||
- **默认请求/响应格式**: `application/json` (部分文件下载接口为 `application/octet-stream`,任务上报为 `multipart/form-data`)
|
||||
|
||||
### 1.2 鉴权中间件与抗侧信道机制 (`auth_middleware`)
|
||||
服务端在配置了 `DCTS_AUTH_TOKEN` (或 `AppState.auth_token`) 时,启用全局 Axum 鉴权中间件。客户端请求需附带正确的 Token,支持以下两种 Header 形式:
|
||||
### 1.2 鉴权机制与权限控制矩阵 (`auth_middleware` & RBAC)
|
||||
|
||||
1. **Bearer Token 方式**:
|
||||
服务端基于角色访问控制 (RBAC) 划分三种请求鉴权级别:
|
||||
|
||||
1. **Admin 角色**:具有系统管理权限(工作流 CRUD/起停、节点凭据审批/吊销/重发、系统恢复)。在 Request Header 中需携带:
|
||||
```http
|
||||
Authorization: Bearer <your_auth_token>
|
||||
Authorization: Bearer <DCTS_ADMIN_TOKEN>
|
||||
# 或
|
||||
x-api-key: <DCTS_ADMIN_TOKEN>
|
||||
```
|
||||
2. **X-API-Key 方式**:
|
||||
2. **Node 角色**:仅限 Worker 节点运行态调用(心跳/抢占任务/汇报/下载数据)。携带管理员审批颁发的专属节点 Token:
|
||||
```http
|
||||
x-api-key: <your_auth_token>
|
||||
Authorization: Bearer <NODE_SPECIFIC_TOKEN>
|
||||
```
|
||||
3. **Public 角色**:无需鉴权直接访问(如 `/login` 管理登录、`/node/register` 提交申请、`/node/check_status` 轮询审批、`/healthz` 健康检查)。
|
||||
|
||||
> [!TIP]
|
||||
> **防侧信道保护**:所有鉴权过程底层完全调用经过高定强优化的恒定长位跨运算度等时比较机制(Constant-Time Comparison),规避了一切从请求响应回车微小毫秒间隔判断探测系统敏感密钥或计算出有效前缀长度的侧信道(Side-Channel Attack)攻击。
|
||||
> **防侧信道保护**:底层调用 Constant-Time 等时比较机制 (`Sha256` 摘要匹配),彻底规避侧信道攻击(Side-Channel Attack)。
|
||||
|
||||
若未通过鉴权,服务端统一返回 `401 Unauthorized` 响应:
|
||||
```text
|
||||
HTTP/1.1 401 Unauthorized
|
||||
Unauthorized: Invalid or missing authentication token
|
||||
```
|
||||
### 1.3 限流机制与错误模型 (Rate Limiting & Unified Error)
|
||||
|
||||
- **API 限流 (Rate Limiting)**:服务端对敏感接口(如 `/login`、`/node/register`)应用了基于 Governor / 漏桶算法的请求限流器。超出速率上限时返回 `429 Too Many Requests`。
|
||||
- **统一错误格式 (AppError)**:所有 RESTful API 的错误响应均格式化为标准 JSON:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "错误原因详细说明",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -384,6 +394,44 @@ Worker 节点向服务端上报的任务计算结果。
|
||||
|
||||
---
|
||||
|
||||
### 3.3 节点凭据与审批管理 API (Admin 角色)
|
||||
|
||||
#### 1. 列出全部节点及凭据状态 (`GET /api/admin/nodes`)
|
||||
- **权限**: Admin 角色
|
||||
- **响应 (`200 OK`)**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "成功获取节点列表",
|
||||
"data": [
|
||||
{
|
||||
"node_id": "node-worker-01",
|
||||
"has_token": true,
|
||||
"is_revoked": false,
|
||||
"issued_at": "2026-07-28T12:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 同意节点接入申请 (`POST /api/admin/nodes/:node_id/approve`)
|
||||
- **权限**: Admin 角色
|
||||
- **说明**: 批准处于待审批状态的 Node,并生成该节点的专属 Token。
|
||||
|
||||
#### 3. 拒绝节点接入申请 (`POST /api/admin/nodes/:node_id/reject`)
|
||||
- **权限**: Admin 角色
|
||||
- **说明**: 拒绝处于待审批状态的 Node 接入。
|
||||
|
||||
#### 4. 吊销节点专属 Token (`POST /api/admin/nodes/:node_id/revoke`)
|
||||
- **权限**: Admin 角色
|
||||
- **说明**: 立即吊销节点专属 Token,被吊销的 Token 无法再通过 Node 鉴权,需重新申请。
|
||||
|
||||
#### 5. 重新颁发节点专属 Token (`POST /api/admin/nodes/:node_id/reissue`)
|
||||
- **权限**: Admin 角色
|
||||
- **说明**: 作废旧 Token 并重新生成新 Token 文本返回。
|
||||
|
||||
---
|
||||
|
||||
## 4. 任务调度与结果上报 API (Task Processing)
|
||||
|
||||
支持 Worker 节点抢占式领用任务与计算结果(含种子 `.7` 文件)上传。
|
||||
@@ -626,6 +674,9 @@ Worker 节点向服务端上报的任务计算结果。
|
||||
}
|
||||
}
|
||||
```
|
||||
> `grid_stats` 为**全部工作流的合计**(跨工作流全局聚合)。多工作流并发运行时,此处展示所有
|
||||
> 工作流 grid_points 的汇总进度;如需查看单个工作流的进度,可读取该工作流各自的 grid_points 统计
|
||||
> (`Database::get_grid_summary_stats(Some(workflow_name))`)。
|
||||
- **curl 示例**:
|
||||
```bash
|
||||
curl -X GET http://localhost:8090/api/status \
|
||||
@@ -634,6 +685,22 @@ Worker 节点向服务端上报的任务计算结果。
|
||||
|
||||
---
|
||||
|
||||
### 7.2 轻量级健康检查端点 (`GET /healthz`)
|
||||
|
||||
- **鉴权**: 否 (Public 免鉴权,专用于 Docker / K8s / Caddy 探针)
|
||||
- **响应 (`200 OK`)**:
|
||||
```json
|
||||
{
|
||||
"status": "ok"
|
||||
}
|
||||
```
|
||||
- **curl 示例**:
|
||||
```bash
|
||||
curl -i http://localhost:8090/healthz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 工作流管理 API (Workflow CRUD & Execution)
|
||||
|
||||
管理恒星大气网格计算工作流 YAML 配置的增删改查、启动与暂停控制。
|
||||
@@ -869,9 +936,10 @@ Worker 节点向服务端上报的任务计算结果。
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **`200 OK`** | 请求正常处理 | JSON / Binary Stream | 操作成功执行。 |
|
||||
| **`400 Bad Request`** | 参数校验失败、缺失关键字段或 YAML 格式错误 | `application/json` / Plain Text | 检查请求 JSON 结构,验证 YAML 配置语法是否正确。 |
|
||||
| **`401 Unauthorized`** | 鉴权失败或缺失 Authorization Header | Plain Text | 确认环境变量 `DCTS_AUTH_TOKEN` 配置,并在 Request Header 中包含正确的 `Bearer <token>` 或 `x-api-key`。 |
|
||||
| **`404 Not Found`** | 资源、种子文件或工作流不存在 | `application/json` / Plain Text | 校验请求 URL 中的资源文件名或工作流 `name` 是否拼写无误。 |
|
||||
| **`500 Internal Server Error`** | 服务端数据库错误、I/O 打开失败或队列异常 | `application/json` / Plain Text | 检查服务端日志以进一步厘清 SQLite 锁冲突、磁盘空间或资源路径问题。 |
|
||||
| **`401 Unauthorized`** | 鉴权失败或缺失 Authorization Header | `application/json` | 确认环境变量配置,并在 Request Header 中包含正确的 Token。 |
|
||||
| **`404 Not Found`** | 资源、种子文件或工作流不存在 | `application/json` | 校验请求 URL 中的资源文件名或工作流 `name` 是否拼写无误。 |
|
||||
| **`429 Too Many Requests`** | API 请求超出速率限制(限流生效) | `application/json` | 降低请求频率或配置漏桶/令牌桶容量参数。 |
|
||||
| **`500 Internal Server Error`** | 服务端数据库错误、I/O 打开失败或队列异常 | `application/json` | 检查服务端日志以进一步厘清 SQLite 锁冲突、磁盘空间或资源路径问题。 |
|
||||
|
||||
---
|
||||
*文档生成于 2026-07-27 | DCTS Server 0.1.0*
|
||||
|
||||
@@ -44,12 +44,15 @@ flowchart TB
|
||||
## 2. 核心组件职责
|
||||
|
||||
### 2.1 Master 服务端 (`server` & Web `dashboard`)
|
||||
- **工作流与可视看板调度**:解析 `config.yaml` 生成多维笛卡尔积参数网格点放入 SQLite 数据库;且自带前端服务透射特性(映射 `dashboard/dist`),开局即在后端服务的相同接口同服下发开机即饮用的富监看运维控制桌仪表网页。
|
||||
- **工作流与多任务隔离**:支持多工作流并发隔离运行(`grid_points` 与 `task_queue` 增加 `workflow_name` 复合唯一索引),调度与重置操作严格隔离在单工作流作用域内。支持旧版 SQLite 数据库启动时无缝平滑迁移。
|
||||
- **安全中间件与 RBAC**:基于角色访问控制 (Admin / Node / Public) 划分 API 权限,内嵌 Bearer Token 校验、Governor / 漏桶算法限流中间件与 CORS 跨域控制,防御侧信道攻击与暴力破解。
|
||||
- **节点凭据生命周期管理**:支持 Worker 节点注册申请、管理员审批授权、Token 吊销与重新颁发全生命周期管理。
|
||||
- **任务调度与分配**:通过 `mq` 队列管理任务生命周期,响应 Worker 的 Claim 请求分配就绪任务。
|
||||
- **状态维护与心跳监测**:后台离线检测线程定期标记超时未心跳的节点为 `offline`,并能将因为断线掉电死机僵挂在其身上的坏死大批网格运算占位点清表并原路全方位无漏损地安全刷进重置任务池中(Requeue)避免死锁失联漏计。
|
||||
- **静态资源与种子分发**:提供原子数据、线列表与 `.7` 大气种子文件的 HTTP 下载和上传接口。
|
||||
- **状态维护与心跳监测**:后台离线检测线程定期标记超时未心跳的节点为 `offline`,并能将僵挂在超时节点上的任务自动回收到队列中(Requeue)。
|
||||
- **ESM 模块化 Web 看板**:前端采用 ESM 模块解耦设计(`state.js`, `api.js`, `components/`),支持节点凭据管理、工作流控制与全局 Toast 通知。
|
||||
|
||||
### 2.2 Worker 计算节点 (`node`)
|
||||
- **弹性扩容与身份标识**:`DCTS_NODE_ID` 未指定或为空时,自动生成基于随机 UUID 的节点 ID(`node-<uuid>`),原生支持 `docker compose --scale node=N` 动态横向扩展多个 Worker 容器。
|
||||
- **环境自适应预热 (Bootstrap)**:启动时核对本地 `./runtime` 运行依赖,缺失时自动向 Master 拉取可执行文件与二进制数据。
|
||||
- **任务抢占与执行 (Claim & Execute)**:根据并发配置轮询抢占任务,调用 `common` 启动子进程链(tlusty / synspec)。
|
||||
- **种子检索与回传 (Seed Sync)**:计算成功后将收敛的大气结构文件(`.7`)与状态 JSON 汇报回服务端。
|
||||
|
||||
+14
-4
@@ -76,12 +76,22 @@ erDiagram
|
||||
|
||||
### 2.2 `grid_points` (网格点物理参数表)
|
||||
存储多维笛卡尔积展开后的每一个独立参数点。
|
||||
- `point_id` (`VARCHAR(128) PRIMARY KEY`):点全局唯一 ID(如 `pt_teff40000_logg600_he-100...`)。
|
||||
- `workflow_name` (`VARCHAR(64) REFERENCES workflows(name)`):所属工作流。
|
||||
- `teff`, `logg`, `he_abund`, `c_abund`, `n_abund`, `o_abund` (`REAL`):物理参数。
|
||||
- `status` (`VARCHAR(32)`):`pending` / `running` / `converged` / `failed`。
|
||||
- `id` (`INTEGER PRIMARY KEY AUTOINCREMENT`):自增主键。
|
||||
- `name` (`TEXT NOT NULL`):点物理唯一名(由 6 维参数生成,如 `t35000_g5.5_he-1_c-2_n-2_o-2`)。
|
||||
- `workflow_name` (`TEXT NOT NULL`):所属工作流。**多工作流分区键**——同一物理点可属于多个工作流,
|
||||
与 `name` 共同构成复合唯一约束 `UNIQUE(workflow_name, name)`。
|
||||
- `teff`, `logg`, `loghe`, `logc`, `logn`, `logo` (`REAL NOT NULL`):6 维物理参数。
|
||||
- `cno_sum` (`REAL NOT NULL`):CNO 丰度之和(调度排序用)。
|
||||
- `wave` (`INTEGER`):按 cno_sum 分组的批次波次(调度优先级用)。
|
||||
- `status` (`VARCHAR(32)`):`pending` / `queued` / `running` / `converged` / `failed`。
|
||||
- `attempt_count` (`INTEGER`):失败重试计数(仅观测用)。
|
||||
- `success_method` (`VARCHAR(32)`):收敛时的成功手段 (`cold_run` 冷启动成功 / `seed_step` 种子步进成功)。
|
||||
|
||||
> **多工作流分区(per-workflow partitioning)**:`grid_points` 与 `task_queue` 均按 `workflow_name` 隔离。
|
||||
> 调度、状态更新、stale 重投、`stop_workflow` 重置都限定在单个工作流内,互不影响。
|
||||
> 历史旧库(无 `workflow_name` 列)在启动时自动迁移:表重建为复合唯一结构,旧行 `workflow_name`
|
||||
> 标记为 `__legacy__`,不干扰新工作流查询。
|
||||
|
||||
### 2.3 `nodes` (计算节点心跳与状态表)
|
||||
- `node_id` (`VARCHAR(64) PRIMARY KEY`):节点唯一标识。
|
||||
- `hostname` (`VARCHAR(128)`):节点主机名或 IP。
|
||||
|
||||
+5
-2
@@ -123,8 +123,11 @@ DCTS 运行时所依赖的物理计算底座二进制文件 `assets/tlusty_stati
|
||||
| `DCTS_PORT` | `8090` | 服务端 HTTP REST API 监听端口 |
|
||||
| `DCTS_DB_PATH` | `data/dcts.db` | 主 SQLite 数据库文件路径(存放节点、网格点及种子记录) |
|
||||
| `DCTS_QUEUE_DB_PATH` | `data/dcts_queue.db` | 任务队列 SQLite 数据库文件路径 |
|
||||
| `DCTS_RESULTS_DIR` | `data/results` | 集中种子仓库与计算总结`conv.json` 保存目录 |
|
||||
| `DCTS_AUTH_TOKEN` | *空* | 服务端 API 鉴权令牌(可选,若配置则需在请求头携带 Bearer Token) |
|
||||
| `DCTS_RESULTS_DIR` | `data/results` | 集中种子仓库与计算总结保存目录 |
|
||||
| `DCTS_BACKUP_DIR` | `data/backups` | 数据库自动/手动备份输出目录 |
|
||||
| `DCTS_ADMIN_TOKEN` | *空* | 管理员控制台与敏感 API 鉴权令牌 |
|
||||
| `DCTS_AUTH_TOKEN` | *空* | 旧版全局 API 鉴权令牌(兼容 Admin 与 Enrollment 校验) |
|
||||
| `DCTS_AUTH_DISABLED` | `false` | 应急开发参数:设置为 `1` 或 `true` 时跳过鉴权 |
|
||||
| `DCTS_STALE_SEC` | `1800` | 任务运行超时重新放回队列的时间上限(秒) |
|
||||
| `DCTS_NODE_STALE_SEC` | `120` | 判定 Worker 节点离线的心跳超时时间(秒) |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user