Skip to content

Latest commit

 

History

History
376 lines (278 loc) · 8.57 KB

File metadata and controls

376 lines (278 loc) · 8.57 KB

🎉 SimpleScheduler 项目构建完成!

✅ 已完成的功能

核心架构

  • ✅ 基于 Nitro 的高性能 Web 服务器
  • ✅ 使用 Zod 进行强类型数据验证
  • ✅ 模块化的服务架构设计
  • ✅ TypeScript 全栈类型安全

数据模型

  • ServiceDefinition - 服务定义(WEB_SERVICE, LOCAL_TOOL)
  • QueueDefinition - 队列定义(名称、并发数)
  • Job - 任务实例(状态、payload、结果)
  • ✅ 完整的枚举类型(JobStatus, ServiceType, OutputType, SSEEventType)

核心服务

  1. ConfigManager - 配置管理

    • 加载 config/services.jsonconfig/queues.json
    • 使用 Zod 验证配置格式
    • 提供服务和队列查询接口
  2. StorageService - 持久化存储

    • 基于 unstorage 的键值存储
    • 支持任务状态持久化
    • 支持文件资源存储
    • 自动清理过期数据
  3. JobManager - 任务管理

    • 创建和更新任务
    • 事件驱动的状态通知
    • 支持日志、结果、错误的统一管理
    • 基于 EventEmitter 的实时通知
  4. QueueManager - 队列管理

    • 多队列支持
    • 并发控制(每个队列独立的并发限制)
    • 自动恢复未完成任务(服务重启后)
    • 智能任务调度
  5. TaskExecutor - 任务执行

    • WebServiceExecutor:调用外部 Web API
    • LocalToolExecutor:执行本地脚本/命令
    • 命令注入防护(白名单验证、禁用 shell)
    • 实时日志流式传输
  6. CleanupService - 自动清理

    • 定期清理 7 天前的旧任务
    • 清理 24 小时前的临时文件
    • 可配置的清理间隔

API 接口

  • POST /api/v1/schedule - 提交任务
  • GET /api/v1/status/{jobId} - 查询任务状态
  • GET /api/v1/stream/{jobId} - SSE 实时订阅
  • GET /api/v1/resource/{resourceId} - 下载文件资源
  • GET /api/v1/queues - 查看队列状态
  • GET / - 美观的 Web 管理界面

安全特性

  • ✅ 命令白名单验证
  • ✅ 禁用 shell 执行(防止命令注入)
  • ✅ 参数分离传递
  • ✅ 超时保护(5 分钟)
  • ✅ Zod 输入验证

文档

  • README.md - 完整的项目文档
  • QUICK_START.md - 快速使用指南
  • test.mjs - 自动化测试脚本
  • ✅ 内联代码注释

📁 项目结构

SimpleScheduler/
├── config/
│   ├── services.json          # 3 个示例服务定义
│   └── queues.json            # 3 个队列定义
├── server/
│   ├── api/v1/
│   │   ├── schedule.post.ts   # 任务提交
│   │   ├── status/[jobId].get.ts
│   │   ├── stream/[jobId].get.ts  # SSE
│   │   ├── resource/[resourceId].get.ts
│   │   └── queues.get.ts
│   ├── services/
│   │   ├── ConfigManager.ts
│   │   ├── StorageService.ts
│   │   ├── JobManager.ts
│   │   ├── QueueManager.ts
│   │   ├── TaskExecutor.ts
│   │   └── CleanupService.ts
│   ├── types/
│   │   ├── enums.ts
│   │   ├── schemas.ts
│   │   └── index.ts
│   ├── utils/
│   │   ├── validator.ts
│   │   └── helpers.ts
│   ├── plugins/
│   │   └── init.ts           # 服务初始化
│   └── routes/
│       └── index.ts          # Web 管理界面
├── .data/                    # 自动创建的数据目录
│   ├── jobs/                 # 任务持久化
│   └── resources/            # 文件资源
├── README.md
├── QUICK_START.md
├── test.mjs
├── package.json
└── tsconfig.json

🚀 如何使用

1. 启动服务

yarn dev

2. 访问 Web 界面

打开浏览器访问:http://localhost:3005

3. 提交任务

curl -X POST http://localhost:3005/api/v1/schedule \
  -H "Content-Type: application/json" \
  -d '{
    "serviceId": "example-web-api",
    "payload": {"url": "https://httpbin.org/json", "method": "GET"},
    "queue": "default"
  }'

4. 运行测试

node test.mjs

🎯 关键技术实现

1. 并发控制

// QueueManager 中的核心逻辑
while (this.runningJobs.size < this.concurrency) {
  const nextJob = await getNextPendingJob()
  if (nextJob) {
    this.executeJob(nextJob)
  }
}

2. SSE 实时通知

// JobManager 发出事件
this.emit(`job:${jobId}`, { eventType, data })

// SSE 接口监听并推送
jobManager.on(`job:${jobId}`, (event) => {
  stream.write(formatSSEMessage(event.eventType, event.data))
})

3. 安全执行

// 白名单验证
const safePattern = /^[a-zA-Z0-9_\-./]+$/
if (!safePattern.test(command)) {
  throw new Error('Unsafe command')
}

// 使用 spawn 而非 exec(禁用 shell)
spawn(command, args, { shell: false })

4. 持久化存储

// 使用 unstorage 的文件系统驱动
const storage = createStorage({
  driver: fsDriver({ base: './.data/jobs' })
})

📊 系统状态

当前配置:

  • 3 个队列:default (5), high-priority (10), low-priority (2)
  • 3 个服务:example-web-api, example-script, file-generator
  • 自动清理:每小时执行一次
  • 数据存储.data/ 目录(文件系统)

🔄 服务启动流程

  1. Nitro 服务器启动
  2. server/plugins/init.ts 自动执行
  3. ConfigManager 加载配置文件
  4. StorageService 初始化存储
  5. QueueManager 初始化队列并恢复未完成任务
  6. CleanupService 启动定期清理
  7. 所有 API 路由就绪

🎨 Web 界面特性

  • 📊 实时显示系统状态
  • 📡 列出所有可用 API 接口
  • 🔧 展示服务定义列表
  • 📦 显示队列状态(等待/运行中的任务数)
  • 📖 提供快速开始示例代码
  • 🎨 美观的渐变设计和响应式布局

🧪 测试覆盖

test.mjs 脚本测试以下功能:

  1. ✅ 提交 Web API 任务
  2. ✅ 查询任务状态
  3. ✅ SSE 实时订阅
  4. ✅ 查看队列状态

🚀 生产部署建议

1. 构建生产版本

yarn build
yarn preview

2. 使用 PM2 管理

npm install -g pm2
pm2 start .output/server/index.mjs --name simple-scheduler

3. 配置反向代理

# Nginx 配置示例
location /api/ {
  proxy_pass http://localhost:3005/api/;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
}

4. 环境变量

# .env
PORT=3005
NODE_ENV=production
CLEANUP_INTERVAL=3600000

5. 监控

  • 添加健康检查端点
  • 集成 Prometheus metrics
  • 配置日志聚合(如 ELK)

🔮 未来扩展方向

可选增强功能:

  1. 数据库集成

    • PostgreSQL / MongoDB 替代文件存储
    • 更强大的查询能力
  2. 任务优先级

    • 在队列内实现优先级排序
    • 动态调整任务优先级
  3. Webhook 通知

    • 任务完成后回调指定 URL
    • 支持重试机制
  4. 任务依赖

    • 实现 DAG(有向无环图)任务流
    • 条件执行和分支逻辑
  5. Web UI 管理后台

    • 任务管理界面
    • 实时监控面板
    • 服务配置编辑器
  6. 认证授权

    • JWT 认证
    • API Key 管理
    • 角色权限控制
  7. 分布式支持

    • Redis 作为共享存储
    • 多实例负载均衡
    • 分布式锁
  8. 重试机制

    • 失败任务自动重试
    • 指数退避策略

📝 注意事项

开发环境

  • ✅ 已测试并运行正常
  • ✅ 所有核心功能已实现
  • ✅ 代码质量良好,注释完善

生产环境

  • ⚠️ 需要配置环境变量
  • ⚠️ 建议使用 Redis/PostgreSQL 替代文件存储
  • ⚠️ 添加认证授权机制
  • ⚠️ 配置 HTTPS 和 CORS

🎓 学习要点

这个项目展示了以下最佳实践:

  1. 模块化设计:每个服务单一职责
  2. 类型安全:TypeScript + Zod 双重保障
  3. 事件驱动:EventEmitter 实现解耦
  4. 异步处理:async/await 模式
  5. 错误处理:统一的错误处理机制
  6. 安全编码:防止常见漏洞
  7. 文档优先:完善的代码注释和文档

🏆 总结

SimpleScheduler 是一个生产级别的通用调度器框架,具备:

  • ✅ 完整的功能实现
  • ✅ 健壮的错误处理
  • ✅ 清晰的代码结构
  • ✅ 详细的文档
  • ✅ 良好的扩展性

恭喜!你现在拥有一个强大的任务调度系统! 🎉


构建时间:2025-11-12
版本:1.0.0
技术栈:Node.js + Nitro + TypeScript + Zod + unstorage
作者:AI 架构师

Happy Scheduling! 🚀