传统crontab痛点

  • 机器故障, 任务停止调度, 甚至crontab配置都找不回来
  • 任务数量多, 单机的资源耗尽, 需要人工迁移到其他机器
  • 需要人工去机器上配置cron, 任务执行的状态不方便查看

分布式架构-核心要素

  • 调度器: 需要高可用, 确保不会因为单点故障停止调度
  • 执行器: 可扩展, 提供大量任务的并行处理能力

常见开源调度框架

  • quartz

image.png

伪分布式设计

  • 分布式网络环境不可靠, RPC异常属于常态
  • Master下发任务RPC异常, 导致master与worker状态不一致
  • worker上报任务RPC异常, 导致Master状态信息落后

异常case:

  • 状态不一致: master下发任务给node1异常, 实际node1收到并开始执行
  • 并发执行: master重试任务下发给node2, 结果node1与node2同时执行一个任务
  • 状态丢失: master更新zookeeper中任务状态异常, 此时master宕机切换standby, 任务仍旧处于旧状态

分布式伪命题

  • 但凡需要经过网络的操作, 都有可能异常
  • 将应用状态放在存储中, 必然会出现内存与存储状态不一致
  • 应用直接利用raft管理状态, 可以确保最终一致, 但成本太高

CAP理论- 常用于分布式存储

  • C: 一致性, 写入后立即读到新值
  • A: 可用性, 通常保障最终一致
  • P: 分区容错性, 分布式必须面对网络分区

image.png

BASE理论- 常用于应用架构

  • 基本可用
  • 软状态
  • 最终一致性

image.png

整体架构

image.png

  • 利用etcd同步全量任务列表到所有的worker节点
  • 每个worker独立调度全量任务, 无需与master产生直接rpc
  • 各个worker利用分布式锁抢占, 解决并发调度相同任务的问题

Mater功能

  • 任务管理Http接口: 新增, 修改, 查看, 删除
  • 任务日志http接口: 查看任务执行历史日志
  • 任务控制http接口: 提供强制结束任务的接口
  • web管理界面: jquery+bootstrap, 前后端分离

image.png

Worker功能

  • 任务同步: 监听etcd中/cron/jobs/目录变化
  • 任务调度: 基于cron表达式, 触发过期任务
  • 任务执行: 协程池并发执行多任务, 基于etcd分布式锁抢占
  • 日志保存: 捕获任务执行输出, 保存到mongoDB

image.png