Job Schedule

JDK 提供的有 ExecutorServiceScheduledExecutorService 提供异步和调度任务,但是存在一些弊病:

  • 基于内存。应用宕机任务丢失

  • 只支持单机,或者是单 JVM 实例。不支持集群,存在单点问题。如果应用是集群部署,存在任务重复执行问题

  • 缺少重试。任务异常后,任务无法通过重试自愈,重新执行

    • 持久化。将任务持久化后就可以容忍 JVM 宕机问题,供后续重试
  • 限流。通过限流保护应用不会因为压力过大宕机

  • 生命周期管理。任务无法启动、停止

  • 动态调整。无法调整任务参数、执行频率

  • 不支持高级任务。任务分片,MapReduce 类型

  • 任务上下游依赖。

  • 监控告警、任务日志查看

关键特性

  • 任务类型
    • 一次性。fire-and-forget
    • 周期性任务
    • 延时任务
    • MapReduce
    • 任务分片
    • 任务广播
    • DAG 任务
  • 调度频率。执行开始时间、结束时间限制,执行次数限制,是否支持秒级调度
    • 固定延迟
    • 固定频率
    • CRON 表达式
  • 任务参数
  • 存储
    • 存储类型。内存,MySQL,Redis,消息队列
    • 任务持久化。是否支持将任务持久化到存储中,任务线程或 JVM 宕机后可以重试任务
  • JDK。8,11,17
  • 生命周期。
    • 任务管理。任务的启动,停止,暂停,恢复等
    • 任务事件监听。
  • 监控、告警、日志白屏化
  • 异步执行。异步执行任务,执行结束后发送任务执行结果
  • 任务阻塞
    • 过期处理策略。任务错过调度时间的处理策略,如服务重启、调度线程阻塞
    • 负载均衡。
    • 阻塞策略。单机串行,丢弃后续调度
    • 队列
  • 任务优先级,任务超时
  • 其他
    • 长耗时
    • 任务进度条

调度任务

周期性执行任务。如固定频率、固定延迟、CRON

异步任务

执行数据下载、导入任务时,往往采用异步任务执行这些长耗时任务。但是对于缺乏重试、监控的 ExecutorService,任务异常时无法重新执行,缺少容错性。如何保证异步任务执行的可靠性就成了这些长耗时任务的关注点。

除此之外还要考虑异步任务性能,为支持数以百万的异步任务执行,需支持异步任务在集群其他节点的执行。

Python 语言的 Celery、Ruby 语言的 sidekiq,提供了简单、高性能、功能齐全的异步任务,只需要简单配置,就可以像在本地调用异步一样,实现集群异步任务。

其他

技术文档