整体架构与核心设计:Go AI 调度平台
基于 go-ai-scheduler 仓库代码梳理项目真实架构,理解四个核心服务、数据流与 AI 辅助能力的设计边界。
架构总览
go-ai-scheduler 是一个 Go 原生的分布式任务调度平台,核心定位很清晰:用 Go 写调度,用 AI 做辅助,不让 AI 参与核心调度决策。
┌──────────┐ HTTP + JWT ┌──────────┐ HTTP Proxy ┌──────────┐
│ Web UI │ ──────────────────→ │ API │ ──────────────────→ │ai-service│
│ :8082 │ │ :8082 │ │ :8083 │
└──────────┘ └────┬─────┘ └──────────┘
│
│ HTTP / gRPC
▼
┌──────────────┐
│ Scheduler │
│ :8081 / :9090│
└──────┬───────┘
│
│ HTTP / gRPC
▼
┌──────────────┐
│ Worker │
│ :8080 │
└──────┬───────┘
│
▼
┌───────────────────────────────────┐
│ MySQL │ Redis (可选) │ etcd │
└───────────────────────────────────┘
整个系统由四个独立进程组成:API、Scheduler、Worker、AI Service。每个都是单 Go 二进制,没有应用服务器,没有 sidecar。
四个核心服务
API Service (:8082)
外部唯一入口。职责包括:
- JWT 认证与 RBAC:admin / operator / viewer 三角色
- 多租户隔离:JWT claims 携带 tenantID,贯穿所有数据查询
- Web Console 托管:静态页面直接由 API 服务提供
- AI Service 代理:/api/v1/chat、/api/v1/advisor 等接口反向代理到 ai-service
- 任务 CRUD:创建、更新、删除、查询任务定义
// 路由注册示例
mux.Handle("/api/v1/tasks", authMiddleware(taskHandler))
mux.Handle("/api/v1/chat", aiProxyMiddleware(aiProxy))
Scheduler (:8081 / :9090 gRPC)
调度控制平面。只有一个 Scheduler 实例是 Leader,其余等待。
核心职责:
- 触发循环:定时扫描到期的 Cron 任务和事件触发任务
- 分发决策:为每个 task instance 选择目标 Worker
- 重试循环:处理失败实例的重新调度
- Leader 选举:通过 MySQL
GET_LOCK或 etcd 保证单 Leader
触发循环工作流程:
1. 检查当前 pending 实例数(背压控制)
2. 从 MySQL 或 Redis 缓存获取到期任务
3. 检查上游依赖是否满足(DAG)
4. 按 shard 拆分为多个 instance
5. 调用 Router 选择 Worker
6. 通过 Dispatcher 发送执行请求
7. 更新下次触发时间
Worker (:8080)
任务执行器。向 Scheduler 注册并维持心跳,等待被分发任务。
支持三种任务类型:
- shell:本地 bash 执行
- http:发起 HTTP 请求
- container:Docker 容器执行
执行完成后通过 HTTP 回调或 gRPC 上报结果。
AI Service (:8083)
AI 辅助服务。与核心调度完全解耦,Scheduler 不依赖它也能正常工作。
核心能力:
| 能力 | 说明 |
|---|---|
| Chat Agent | 对话式 AI,带 12 个工具函数,SSE/WebSocket 双协议 |
| Log Analysis | 对失败实例的日志进行 AI 根因分析 |
| Advisor | 基于系统指标生成调度优化建议 |
| Task Parser | 自然语言 → 任务定义 |
| Duration Prediction | 基于历史数据预测任务执行时间 |
| Trend Analysis | 全系统趋势分析与建议 |
数据流
一条任务从定义到执行的完整链路:
Rendering diagram...
注意 AI 的介入点是异步、可选的。Scheduler 的核心路径不等待 AI 返回。
存储设计
| 存储 | 用途 | 是否必需 |
|---|---|---|
| MySQL | 所有持久化状态:任务、实例、Worker、AI 记录、会话 | 是 |
| Redis | 缓存:到期任务、Worker 状态、负载、AI 查询缓存 | 否,降级到 MySQL |
| etcd | Leader 选举(替代 MySQL GET_LOCK) | 否,默认用 MySQL |
设计约束
项目里有几条硬约束,体现了设计者对正确性的坚持:
- AI 不允许决定任务是否运行 —— AI 只做建议,调度决策权在 Scheduler
- Worker 重试必须 centralized —— 通过 Scheduler 统一重试,避免多个 Worker 重复执行
- Redis 是可选的 —— 系统在没有 Redis 时也能正确运行,只是性能降级
- 所有服务都是单二进制 —— 没有应用服务器,没有 sidecar,部署简单
与同类系统的对比
| 特性 | go-ai-scheduler | Airflow | K8s CronJob | Quartz |
|---|---|---|---|---|
| 语言 | Go | Python | Go (K8s 本身) | Java |
| AI 辅助 | 原生集成 | 插件/扩展 | 无 | 无 |
| 任务类型 | shell/http/container | Python Operator | Pod | Java Job |
| 分布式调度 | 内置 Leader 选举 | 需 Celery/DB | K8s 原生 | 需集群配置 |
| 多租户 | JWT + RBAC | 较弱 | Namespace | 无 |
| 依赖 DAG | 内置 | 原生支持 | 无 | 无 |
| 背压控制 | 内置 | 有限 | 无 | 无 |
小结
go-ai-scheduler 的架构设计有几个值得关注的点:
- Go 原生:没有 JVM、没有 Python 运行时,单二进制部署
- AI 辅助而非替代:AI 在旁路提供能力,不阻塞核心调度
- 分层清晰:API 管入口、Scheduler 管决策、Worker 管执行、AI Service 管智能
- 渐进式可选:Redis 可选、etcd 可选、AI 可选,每去掉一层系统仍然可用
后续文章将逐个深入调度引擎、Leader 选举、任务分发、Worker 执行、重试机制、AI 辅助能力和部署实践。