介绍

Openjob 基于Akka架构的新一代分布式任务调度框架。反对多种定时工作、延时工作、工作流设计,采纳无中心化架构,底层应用一致性分片算法,反对有限程度扩容。

  • 高牢靠

    • 分布式无状态设计,采纳 Master/Worker 架构,反对多样的数据库(H2/MySQL/PostgreSQL/Oracle/TiDB)
  • 高性能

    • 底层应用一致性分片算法,全程无锁化设计,任务调度准确到秒级别,反对轻量级分布式计算、有限程度扩容。
  • 定时调度

    • 反对分布式定时工作、固定频率工作、高性能秒级任务、一次性工作定时调度。
  • 分布式计算

    • 反对单机、播送、Map、MapReduce 和分片多种分布式编程模型,轻松实现大数据分布式计算。
  • 延时工作

    • 基于 Redis 实现高性能延时工作,底层实现工作多级存储,提供丰盛的统计和报表。
  • 工作流

    • 内置工作流调度引擎,反对可视化 DAG 设计,简略高效实现简单任务调度。
  • 权限治理

    • 欠缺的用户治理,反对菜单、按钮以及数据权限设置,灵便治理用户权限
  • 报警监控

    • 全面的监控指标,丰盛及时的报警形式,便于运维人员疾速定位和解决线上问题。
  • 跨语言

    • 原生反对 Java/Go/PHP/Python 多语言 ,以及Spring Boot、Gin、Swoft 等框架集成。

如果您正在寻找一款高性能的分布式任务调度框架,反对定时工作、延时工作、轻量级计算、工作流编排,并且反对多种编程语言,那么 Openjob 必定是不二之选(https://github.com/open-job/openjob)。

更新内容

openjob 公布至今已更新到1.0.7 新增反对H2/TiDB 数据库,新增秒级任务、固定频率工作、播送工作、分片工作、Map Reduce 轻量计算。

秒级任务

秒级任务,反对1\~60秒距离的秒级提早调度,即每次工作执行实现后,距离秒级工夫再次触发调度,实用于对实时性要求比拟高的业务。

劣势

  • 高牢靠:秒级别工作具备高牢靠的个性,如果某台机器宕机,能够在另一台机器上从新运行。
  • 丰盛的工作类型:秒级别工作属于定时调度类型,能够实用于所有的工作类型和执行形式。

固定频率工作

因为Crontab必须被60整除,如果须要每隔50分钟执行一次调度,则Cron无奈反对。

Map Reduce

MapReduce 模型是轻量级分布式跑批工作。通过 MapProcessor 或 MapReduceProcessor 接口实现。绝对于传统的大数据跑批(例如Hadoop、Spark等),MapReduce无需将数据导入大数据平台,且无额定存储及计算成本,即可实现秒级别海量数据处理,具备成本低、速度快、编程简略等个性。

/** * @author stelin swoft@qq.com * @since 1.0.7 */@Component("mapReduceTestProcessor")public class MapReduceTestProcessor implements MapReduceProcessor {    private static final Logger logger = LoggerFactory.getLogger("openjob");    private static final String TWO_NAME = "TASK_TWO";    private static final String THREE_NAME = "TASK_THREE";    @Override    public ProcessResult process(JobContext context) {        if (context.isRoot()) {            List<MapChildTaskTest> tasks = new ArrayList<>();            for (int i = 1; i < 5; i++) {                tasks.add(new MapChildTaskTest(i));            }            logger.info("Map Reduce root task mapList={}", tasks);            return this.map(tasks, TWO_NAME);        }        if (context.isTask(TWO_NAME)) {            MapChildTaskTest task = (MapChildTaskTest) context.getTask();            List<MapChildTaskTest> tasks = new ArrayList<>();            for (int i = 1; i < task.getId()*2; i++) {                tasks.add(new MapChildTaskTest(i));            }            logger.info("Map Reduce task two mapList={}", tasks);            return this.map(tasks, THREE_NAME);        }        if (context.isTask(THREE_NAME)) {            MapChildTaskTest task = (MapChildTaskTest) context.getTask();            logger.info("Map Reduce task three mapTask={}", task);            return new ProcessResult(true, String.valueOf(task.getId() * 2));        }        return ProcessResult.success();    }    @Override    public ProcessResult reduce(JobContext jobContext) {        List<String> resultList = jobContext.getTaskResultList().stream().map(TaskResult::getResult)                .collect(Collectors.toList());        logger.info("Map Reduce resultList={}", resultList);        return ProcessResult.success();    }    @Data    @AllArgsConstructor    @NoArgsConstructor    public static class MapChildTaskTest {        private Integer id;    }}

分片工作

分片模型次要蕴含动态分片和动静分片:

  • 动态分片:次要场景是解决固定的分片数,例如分库分表中固定 256 个库,须要若干台机器分布式去解决。
  • 动静分片:次要场景是分布式解决未知数据量的数据,例如一张大表在不停变更,须要分布式跑批。此时须要应用 MapReduce 工作

工作个性

  • 兼容 elastic-job 的动态分片模型。
  • 反对 Java、PHP 、Python、Shell、Go四种语言。
  • 高可用:分片工作执行机器异样时,会动态分配到其它失常机器执行工作。
  • 流量管制:能够设置单机子工作并发数。例如有 100 个分片,一共 3 台机器,能够管制最多 5 个分片并发执行,其它在队列中期待。
  • 失败重试:子工作执行失败异样时,主动重试。
/** * @author stelin swoft@qq.com * @since 1.0.7 */@Componentpublic class ShardingAnnotationProcessor {    private static final Logger logger = LoggerFactory.getLogger("openjob");    @Openjob("annotationShardingProcessor")    public ProcessResult shardingProcessor(JobContext jobContext) {        logger.info("Sharding annotation processor execute success! shardingId={} shardingNum={} shardingParams={}",                jobContext.getShardingId(), jobContext.getShardingNum(), jobContext.getShardingParam());        logger.info("jobContext={}", jobContext);        return ProcessResult.success();    }}

播送工作

播送工作类型的工作实例会播送到利用对应的所有Worker上执行,当所有Worker都执行实现,该工作才算实现,任意一台Worker执行失败,工作就算失败。

利用场景

  • 批量操作

    • 定时播送所有机器运行某个脚本。
    • 定时播送所有机器清理数据。
    • 动静启动每台机器的某个服务
  • 数据聚合

    • 应用JavaProcessor->preProcess 初始化
    • 每台机器执行 process 时,依据本人业务返回 result。
    • 执行 postProcess,获取所有机器的执行后果做汇总。

工作个性

播送工作类型能够抉择多种,例如脚本或者Java工作。如果抉择Java,还反对preProcess和postProcess高级个性。

  • preProcess 会在每台机器执行 process 之前执行,且只会执行一次。
  • process 每天机器理论工作执行逻辑。
  • postProcess 会在每台机器执行 process 实现且都胜利执行之后执行一次,能够返回后果,作为工作流数据传输。
/** * @author stelin swoft@qq.com * @since 1.0.7 */@Component("broadcastPostProcessor")public class BroadcastProcessor implements JavaProcessor {    private static final Logger logger = LoggerFactory.getLogger("openjob");    @Override    public void preProcess(JobContext context) {        logger.info("Broadcast pre process!");    }    @Override    public ProcessResult process(JobContext context) throws Exception {        logger.info("Broadcast process!");        return new ProcessResult(true, "{\"data\":\"result data\"}");    }    @Override    public ProcessResult postProcess(JobContext context) {        logger.info("Broadcast post process taskList={}", context.getTaskResultList());        System.out.println(context.getTaskResultList());        return ProcessResult.success();    }}

更多内容

  • 官网: https://openjob.io
  • Github: https://github.com/open-job/openjob
  • 在线体验: https://demo.openjob.io

    • openjob
    • openjob.io
  • QQ交换群: 849015265