ADK-gateway/网关架构流程图.md
2026-08-04 17:20:08 +08:00

237 lines
8.9 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.

# 网关Gateway项目架构流程图
> 基于代码现状绘制的架构图backend + frontend + agent 联动)。
> 端口:后端 `:8000`、前端 `:5173`、Agent `:8001`、Redis 远程实例 `45.207.192.237:56987/0`。
---
## 一、系统总体架构图(分层)
```mermaid
flowchart TB
subgraph OUT["外部调用方"]
CLI["CLI 客户端 / 模型对话<br/>提交任务(带 auth"]
end
subgraph FE["前端运维后台Vue3 + Vite + Element Plus:5173"]
TV["TaskView 任务管理<br/>列表/筛选/详情/取消/重置"]
AV["AgentView Agent 管理<br/>卡片/标签/负载/下线"]
LV["LogView 日志审计<br/>按 request_id/agent_id 筛选"]
CV["ControlView 总览<br/>任务/Agent 统计"]
API["api/index.ts<br/>fetch 封装(/api/admin/*"]
end
subgraph GW["网关后端FastAPI + Uvicorn:8000"]
direction TB
subgraph API_L["API 层app/api/"]
A1["/api/cli/*<br/>任务提交"]
A2["/api/agent/*<br/>注册/心跳/结果回传"]
A3["/api/admin/*<br/>运维后台查询与管控"]
end
subgraph SVC["服务层app/services/"]
S1["TaskService 任务池<br/>受理/取消/重置/超时"]
S2["AgentService Agent 池<br/>注册/心跳/下线/剔除"]
S3["Scheduler 规则调度<br/>选人→绑定→推送→回退"]
S4["RelayService 通信中转<br/>正向推送/反向收结果"]
S5["HeartbeatService<br/>心跳扫描60s"]
S6["TimeoutService<br/>任务超时检查5s"]
end
subgraph REPO["存储层app/repository/"]
R1["TaskRepo"]
R2["AgentRepo"]
R3["LogRepo"]
end
subgraph LOOP["后台循环scheduler_loop.py"]
L1["heartbeat_loop<br/>Lock:lock:heartbeat"]
L2["dispatch_loop2s<br/>Lock:lock:scheduler"]
L3["timeout_loop<br/>Lock:lock:timeout"]
end
end
subgraph RD["Redis 存储DB0"]
K1["task:info:{id} Hash<br/>task:pending / task:running Set"]
K2["agent:info:{id} Hash<br/>agent:all / agent:tag:{tag} Set"]
K3["agent:heartbeat ZSet"]
K4["lock:* 分布式锁"]
K5["log:audit List"]
end
subgraph AG["Agent 服务ADK ApiServer:8001"]
direction TB
AG0["api_server.py<br/>REST /run /run_sse<br/>SQLite 会话 / InMemory 记忆"]
AG1["task_receiver.py<br/>POST /tasks/{id}<br/>校验 auth → 202 → 后台线程"]
AG2["gateway_client.py<br/>注册 / 心跳 / 回传结果"]
AG3["ADK InMemoryRunner<br/>执行 dev_appmy_agent"]
end
CLI -->|"POST /api/cli/tasks"| A1
FE --> API
API -->|"/api/admin/*"| A3
A1 --> S1
A2 --> S2
A3 --> S1 & S2
S1 & S2 & S3 & S4 & S5 & S6 --> R1 & R2 & R3
L1 -->|"调用"| S5
L2 -->|"调用"| S3
L3 -->|"调用"| S6
S5 -->|"Lock"| K4
S3 -->|"Lock"| K4
R1 & R2 & R3 --> K1 & K2 & K3 & K5
S3 -->|"Scheduler 选中 Agent"| S4
S4 -->|"POST {endpoint}/tasks/{request_id}<br/>期望 202"| AG1
AG1 -->|"校验通过后后台线程"| AG3
AG3 -->|"执行完成"| AG2
AG2 -->|"POST /api/agent/result"| A2
AG2 -->|"心跳 /api/agent/heartbeat10s"| A2
```
---
## 二、任务全生命周期时序图(完整闭环)
```mermaid
sequenceDiagram
autonumber
participant CLI as CLI / 对话模型
participant GW as 网关后端FastAPI :8000
participant RD as Redis
participant LOOP as SchedulerLoop 后台循环
participant AG as Agent 服务(:8001
participant ADK as ADK InMemoryRunner
Note over AG,ADK: Agent 启动register → 每 10s heartbeat
CLI->>GW: POST /api/cli/tasks {auth, task_type, tags, payload}
GW->>GW: TaskService.submit幂等RequestID 复用)
GW->>RD: hset task:info:{id} + sadd task:pending
GW-->>CLI: 200 {request_id}
loop dispatch_loop每 2s持 lock:scheduler
LOOP->>RD: 取 task:pending 成员
LOOP->>GW: Scheduler.dispatch_pending(batch)
GW->>RD: AgentRepo.by_tags(tags) 标签匹配
GW->>GW: 负载过滤load < max_concurrent
GW->>GW: 最低负载 + 在线最久者优先
GW->>RD: 任务置 running + 绑定 agent_id<br/>task:pending→task:runningagent 负载 +1
GW->>AG: RelayService.dispatch_command<br/>POST {endpoint}/tasks/{id} {auth, payload}
alt 推送成功202
AG->>AG: 校验 auth → 后台线程接收任务
AG-->>GW: 202 {ok, request_id, status:"accepted"}
AG->>ADK: 运行 agentInMemoryRunner.run_async
ADK-->>AG: 最终输出文本
AG->>GW: POST /api/agent/result {success, progress:100, result}
GW->>RD: 更新任务 success + 释放 agent 负载<br/>task:running 移除
GW-->>CLI: (前端可查)
else 推送失败(网络错误 / 非 202
AG-->>GW: 4xx/5xx 或无响应
GW->>RD: 回退:任务置 pending + 解绑 + 释放负载<br/>task:running→task:pending
end
end
Note over LOOP,RD: heartbeat_loop60s 扫 agent:heartbeat ZSet<br/>超 120s 未心跳 → 标记 offline<br/>timeout_loop5s 扫 running超时 → failed
```
---
## 三、规则调度决策流程Scheduler
```mermaid
flowchart LR
START(["dispatch_pending<br/>取 task:pending 批量"]) --> T1{"任务存在且为 pending?"}
T1 -- 否 --> END(["跳过"])
T1 -- 是 --> T2{"按 task_tags 标签匹配<br/>AgentRepo.by_tags(tags)"}
T2 -- 无候选 --> END2(["保持 pending<br/>等待下次调度"])
T2 -- 有候选 --> T3["负载过滤<br/>current_load < max_concurrent"]
T3 -- 空 --> END2
T3 -- 非空 --> T4["排序:最低负载优先<br/>负载相同时在线最久优先"]
T4 --> T5["绑定 Agent<br/>task:info 置 running + agent_id<br/>task:pending→task:running"]
T5 --> T6["agent 负载 +1<br/>adjust_load(agent, +1)"]
T6 --> T7["RelayService.dispatch_command<br/>POST {endpoint}/tasks/{id}"]
T7 --> T8{"HTTP 202?"}
T8 -- 是 --> OK(["下发成功<br/>记录 dispatch 日志"])
T8 -- 否 --> T9["回退task 置 pending + 解绑<br/>task:running→task:pending<br/>agent 负载 -1"]
T9 --> END2
```
---
## 四、Agent 端任务处理流程
```mermaid
flowchart TB
RECV["POST {endpoint}/tasks/{request_id}"] --> AUTH{"auth == GATEWAY_AUTH?"}
AUTH -- 否 --> 401["401 invalid auth"]
AUTH -- 是 --> THREAD["启动 daemon 后台线程<br/>(立即返回 202 accepted"]
THREAD --> PROMPT["payload → prompt<br/>prompt / cmd / 兜底序列化)"]
PROMPT --> RUN["InMemoryRunner.run_async<br/>user_id=gateway, session=task-{id}"]
RUN --> OUT["收集最终文本输出"]
OUT --> REP["gateway_client.report_result<br/>POST /api/agent/result"]
RUN --> ERR["异常捕获"]
ERR --> REPF["report_result(status=failed, error_info)"]
```
---
## 五、Redis 数据结构一览
| 前缀 / 键 | 类型 | 用途 |
| --- | --- | --- |
| `task:info:{request_id}` | Hash | 任务全量信息(状态/绑定 Agent/进度/结果TTL 24h |
| `task:pending` | Set | 待调度任务索引 |
| `task:running` | Set | 执行中任务索引 |
| `agent:info:{agent_id}` | Hash | Agent 信息endpoint/标签/并发上限/负载/心跳时间) |
| `agent:all` | Set | 全部 Agent 索引 |
| `agent:tag:{tag}` | Set | 能力标签 → Agent 索引(调度匹配用) |
| `agent:heartbeat` | ZSet | score=最后心跳时间戳(剔除离线用) |
| `lock:heartbeat` / `lock:scheduler` / `lock:timeout` | String | 分布式锁,防多实例重复执行后台循环 |
| `log:audit` | List | 全链路审计日志dispatch/progress/result |
---
## 六、技术栈与端口汇总
```mermaid
flowchart LR
subgraph 后端
B["Python + FastAPI + Uvicorn<br/>redis-py(asyncio) + httpx<br/>端口 8000"]
end
subgraph 前端
F["Vue 3 + Vite + Element Plus<br/>端口 5173/api 代理到 8000"]
end
subgraph Agent
A["Python + Google ADK v2.5<br/>FastAPI ApiServer + InMemoryRunner<br/>端口 8001"]
end
subgraph 存储
R["Redis远程 45.207.192.237:56987/0<br/>任务池 + Agent 池 + 索引 + 日志 + 锁"]
end
B <--> R
B <-->|"HTTP 推送 / 结果回传"| A
F -->|"/api/admin/*"| B
```
---
## 七、任务状态机
```mermaid
stateDiagram-v2
[*] --> pending: submit 受理(幂等)
pending --> running: 调度器选 Agent 并推送成功
pending --> pending: 无可用 Agent / 推送失败回退
running --> success: Agent 回传 result(success)
running --> failed: Agent 回传 failed
running --> failed: 超时 / 用户取消
pending --> failed: 用户取消
success --> pending: 手动重置(重新调度)
failed --> pending: 手动重置(重新调度)
success --> [*]: TTL 归档
failed --> [*]: TTL 归档
```