Skip to content

开发工具箱-远程执行 RemoteRun

开发一个api服务,这个服务的功能就是,接受客户端发来的tasks,执行tasks,tasks的主要内容就是执行服务器的某些脚本; 并最好能实时返回执行日志; 另外服务端对tasks请求落库持久化,能实现管理,对执行日志进行归档处理,路径落库。

开发工具箱系列是为自己的工作减轻复杂度和自动化的工具

API服务概要设计

  1. 核心功能模块
  • 任务接收与管理

    • 提供RESTful接口接收客户端提交的脚本任务(如POST /tasks),支持任务优先级、超时时间、重试策略等元数据。

    • 任务唯一标识生成(如UUID),状态机设计(待执行、执行中、成功、失败、超时)。

  • 任务执行引擎

    • 脚本执行隔离:通过容器(如Docker)或沙箱机制隔离任务执行环境,避免资源冲突。

    • 异步执行与队列:使用消息队列(如RabbitMQ、Kafka)或内存队列实现任务调度,支持并发控制。

  • 实时日志处理

    • 流式日志推送:通过SSE(Server-Sent Events)或WebSocket实时推送执行日志至客户端。

    • 日志归档:将日志按任务ID、时间戳存储至文件系统(如MinIO)或数据库,路径信息落库(如MySQL)。

  • 持久化与容灾

    • 任务持久化:任务元数据(脚本路径、参数、状态)存入数据库,支持分库分表应对高并发。

    • 异常恢复:通过定时任务扫描未完成的任务,结合重试机制保障任务最终一致性。

  • 监控与告警

    • 执行状态监控:记录任务耗时、成功率等指标,集成Prometheus+Grafana可视化。

    • 异常告警:对失败任务触发邮件、钉钉等通知。

  1. 数据库设计
  • 任务表(tasks)

    sql
    CREATE TABLE tasks (
      id VARCHAR(36) PRIMARY KEY, -- 任务ID
      script_path VARCHAR(255) NOT NULL, -- 脚本路径
      params JSON, -- 执行参数
      status ENUM('pending', 'running', 'success', 'failed', 'timeout'),
      priority INT DEFAULT 0, -- 优先级
      created_at DATETIME,
      updated_at DATETIME,
      logs_path VARCHAR(255) -- 日志存储路径
    );
  • 日志表(task_logs)

    sql
    CREATE TABLE task_logs (
      task_id VARCHAR(36),
      log_time DATETIME,
      content TEXT,
      FOREIGN KEY (task_id) REFERENCES tasks(id)
    );
  1. API接口设计
  • 提交任务
    POST /tasks
    请求体:{ "script_path": "/scripts/backup.sh", "params": {"dir": "/data"}, "priority": 1 }
  • 查询任务状态
    GET /tasks/{id}
  • 实时日志订阅
    GET /tasks/{id}/logs(SSE流)

基于Go实现API服务的详细设计

一、核心模块实现方案

  1. 任务接收与管理模块

    • RESTful API设计

      使用Gin框架实现任务提交接口(POST /tasks)和状态查询接口(GET /tasks/{id}),支持JSON格式请求体,包含脚本路径、参数、优先级等元数据。
      示例代码片段:

      go
      router := gin.Default()
      router.POST("/tasks", func(c *gin.Context) {
          var task TaskRequest
          if err := c.ShouldBindJSON(&task); err != nil {
              c.JSON(400, gin.H{"error": "Invalid request"})
              return
          }
          taskID := generateUUID()
          // 落库并加入队列
          c.JSON(201, gin.H{"id": taskID})
      })
  2. 任务执行引擎

    • 并发控制与隔离

      采用Worker Pool模式,通过缓冲通道(chan Task)控制并发数(如限制10个并行任务)。结合os/exec执行脚本,使用Docker容器或syscallChroot隔离执行环境,防止资源冲突。 示例代码片段:

      go
      type WorkerPool struct {
          tasks chan Task
          wg    sync.WaitGroup
      }
      func (wp *WorkerPool) Start() {
          for i := 0; i < 10; i++ {
              wp.wg.Add(1)
              go func() {
                  defer wp.wg.Done()
                  for task := range wp.tasks {
                      cmd := exec.CommandContext(task.Ctx, "sh", task.ScriptPath)
                      output, _ := cmd.CombinedOutput()
                      // 推送日志并更新状态
                  }
              }()
          }
      }
  3. 实时日志推送

    • SSE(Server-Sent Events)实现

      通过Gin的Stream方法推送日志流,客户端订阅GET /tasks/{id}/logs接口。每条日志以data: {log}\n\n格式发送,支持自动重连。 示例代码片段:

      go
      func (c *gin.Context) {
          taskID := c.Param("id")
          c.Stream(func(w io.Writer) bool {
              log := <-getLogChannel(taskID) // 从日志通道读取
              fmt.Fprintf(w, "data: %s\n\n", log)
              return true
          })
      }
  4. 持久化与容灾

    • 数据库设计

      使用MySQL或PostgreSQL存储任务元数据和日志路径,表结构如下:

      sql
      CREATE TABLE tasks (
          id VARCHAR(36) PRIMARY KEY,
          script_path VARCHAR(255),
          status ENUM('pending', 'running', 'success', 'failed'),
          created_at DATETIME,
          logs_path VARCHAR(255)
      );

      结合GORM库实现ORM映射,事务保证数据一致性。

二、Go语言优势与关键技术选型

  1. 高并发与轻量化

    • Goroutine调度:单机支持万级并发任务,通过runtime.GOMAXPROCS优化CPU绑定任务。

    • 编译为二进制:生成<10MB的独立可执行文件,适合Docker容器化部署(Alpine镜像仅~5MB)。

  2. 关键库与工具链

    • 框架:Gin(API路由)、Asynq(任务队列)。

    • 日志管理:Zap高性能日志库,结合Lumberjack实现日志轮转。

    • 监控:Prometheus客户端收集任务耗时、成功率指标,Grafana可视化。

三、扩展建议

  1. 安全增强

    • 脚本执行前校验数字签名,防止恶意代码注入。

    • 使用seccompgVisor加强容器隔离。

  2. 任务优先级调度
    基于Redis的Sorted Set实现动态优先级队列,高优先级任务插队执行。

  3. 日志脱敏与审计
    在日志输出层动态过滤敏感信息(如密钥),记录操作审计日志。

四、参考实现代码结构

.
├── main.go             # API入口
├── internal
│   ├── api             # Gin路由层
│   ├── task            # 任务调度逻辑
│   ├── persistence     # 数据库ORM(GORM)
│   └── sse             # SSE推送模块
├── scripts             # 可执行脚本目录
└── Dockerfile          # 多阶段构建优化镜像