Easy Task —— 强大而简单的分布式任务调度平台

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

Easy Task 概述

github: https://github.com/cehome-com/easy-task
简单易用的分布式任务调度平台。来源于淘宝彩票调度平台,并先后在淘宝内容抓取平台和铁甲二手机任务调度平台中使用。具有如下特点:

  • 去中心化。
  • 支持上百台不同业务的应用服务器接入。任务在每个应用上独立执行,充分利用应用本身资源。
  • 故障转移。应用如有多台执行机器,一台机器挂掉,其上的任务会切到其它机器。
  • 管理控制台统一对任务修改、启动、停止等。控制台挂掉不影响任务的执行。
  • 可以在线查看任务日志,实时了解任务执行情况。

架构图

快速体验

下载并启动一个控制台。控制台同时也是worker,也能执行任务,缺省会启动一个内置的demoPlugin任务。

  • 下载并启动

1)方式一:到release中下载或直接下载可执行jar包 https://github.com/cehome-com/resource/raw/master/easy-task/2.0.3/task-console.jar

然后执行命令启动: java -jar task-console.jar

2) 方式二:直接剪出task-console spring boot代码模块,导入IDE中,执行com.cehome.task.console.TaskConsoleApplication启动。

如果你想快速部署一套简单可用的调度系统,可以采用方式二,在task-console代码里面添加插件,并部署使用。

如果你有多个应用,想接入调度平台,采用方式一,部署的console只做管理,不做任务执行。

demo图

  • 点击“查看日志”按钮,可以看到任务执行日志(如果没有,可以停10秒再刷新一下)
  • 点击“修改”查看或修改任务配置。系统基于spring,Bean名称“demoPlugin"就是内置的一个spring bean。
  • 点击“停止”可以停止任务。

注:

1)控制台缺省内置了一个H2数据库(端口9092)来保存任务配置。你也可以采用外部H2或mysql数据库。

2)采用方式二剪出task-console代码模块,例子中的demoPlugin对应类为com.cehome.task.console.DemoPlugin,你可以直接修改此插件。

模拟客户端应用(worker)接入调度平台

实际使用中,console只是管理任务,不执行任务,任务是在客户端应用中执行的。下面模拟app1和app2两个应用接入调度平台。为了方便,还是用task-console.jar来模拟。执行前,先保证上面的console还在运行状态。

  • 启动另一个命令行窗口,执行如下命令启动app1(端口为8091)

java -jar task-console.jar --task.factory.appName=app1 --server.port=8091

-启动另一个命令行窗口,执行如下命令启动app2, (端口为8092)

java -jar task-console.jar --task.factory.appName=app2 --server.port=8092

  • 访问http://localhost:8080 ,点击列表中demo的“修改”按钮,弹出修改界面,点击“应用”下拉框,应该能看到app1、app2也在里面,选择app2,然后保存并关闭。
  • 观察app2的命令行输出窗口,发现demo已经转移到在app2中执行了。

现有spring boot应用接入调度平台

以 task-spring-boot-client-demo 模块来说明spring boot应用如何接入调度平台。

  • 增加依赖
        <dependency>
            <groupId>com.cehome</groupId>
            <artifactId>task</artifactId>
            <version>2.0.3</version>
        </dependency>
  • 加入@EnableTimeTaskClient注解
package com.cehome.task.client.demo;

import com.cehome.task.annotation.EnableTimeTaskClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableTimeTaskClient
public class BootApplication {
    public static void main(String[] args) {
        SpringApplication.run(BootApplication.class,args);
    }

}
  • 修改配置信息application.properties

需求配置的信息说明:

task.factory.appName - 应用名称,不同应用应该不一样。

task.factory.name - 集群名称,同时也是数据库表名,定了以后不要随意改动。
task.datasource.* 配置数据库信息,支持H2和mysql数据库,建议生产环境使用mysql数据库。

task.log.path - logback任务日志输出路径。
task.log.packages - 任务执行类所在包名,记录日志用。多个包名用半角分号隔开。如果不好确定,就用ROOT根日志。

spring.application.name=boot-client-demo
server.port=8081

#------  main options --------
#应用的名称
task.factory.appName=boot-client-demo
#集群名称(同时也是数据库表名)
task.factory.name=easy_task

#h2数据库配置
task.datasource.driverClassName=org.h2.Driver
task.datasource.url=jdbc:h2:tcp://localhost:9092/~/easy_task_db;MODE=MYSQL
task.datasource.username=sa
task.datasource.password=

#------  client options --------
task.log.packages=ROOT
task.log.path=/logs/easy_task/boot_demo
  • 开发任务插件

任务插件可以继承com.cehome.task.client.TimeTaskPlugin,由于执行方法是run()是固定的,在console配置任务信息时候就可以不指定方法名。stop()方法会在点击停止任务时候触发,代码应用停止任务执行和释放必要的资源。

package com.cehome.task.client.demo;

import com.alibaba.fastjson.JSONObject;
import com.cehome.task.client.TimeTaskContext;
import com.cehome.task.client.TimeTaskPlugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.Inet4Address;

@Component
public class BootDemoPlugin extends TimeTaskPlugin {
    private static final Logger logger = LoggerFactory.getLogger(BootDemoPlugin.class);
    @Override
    public void run(TimeTaskContext context, JSONObject args) throws Exception {
        logger.info("plugin class name="+this);
        logger.info("task id="+context.getId()+",name="+context.getName());
        logger.info("task run on ip="+ Inet4Address.getLocalHost().getHostAddress());
        logger.info("task run count="+context.getRunTimes());
    }

    @Override
    public void stop(TimeTaskContext context) throws Exception {
        logger.info("task "+context.getName()+" is stopped ");
    }
}


任务插件也可以是普通的spring bean,但在console配置任务信息时候,需要指定要执行的方法。

  • 启动应用task-spring-boot-client-demo
  • 访问http://localhost:8080 (确保控制台是启动状态的),点击“添加”任务,
    “应用”选择“boot-client-demo”;计划时间填5s(5秒);Bean名称跟上面开发插件一致,填写“bootDemoPlugin”;其它必填字段自己随意。

添加任务

  • 保存并关闭,点击“启动”,然后过10多秒钟点击“查看”日志,如果看到“task run……”日志,说明一切正常。
    -

现有spring mvc应用接入调度平台

以 task-spring-mvc-client-demo 模块来说明。

  • 增加依赖
        <dependency>
            <groupId>com.cehome</groupId>
            <artifactId>task</artifactId>
            <version>2.0.3</version>
        </dependency>
  • spring xml中导入bean:
<import resource="classpath*:task-client-spring-config.xml"></import>
  • 在spring xml 中引入配置信息spring/config.properties
  <context:annotation-config/>
<context:property-placeholder location="classpath*:spring/config.properties"/>
  • 在对应的spring/config.properties添加配置信息:

task.factory.appName - 应用名称,不同应用应该不一样。

task.factory.name - 集群名称,同时也是数据库表名,定了以后不要随意改动。
task.datasource.* 配置数据库信息,支持H2和mysql数据库,建议生产环境使用mysql数据库。

task.log.path - logback任务日志输出路径。
task.log.packages - 任务执行类所在包名,记录日志用。多个包名用半角分号隔开。如果不好确定,就用ROOT根日志。

task.factory.appName=mvc-client-demo
task.factory.name=easy_task

#h2
task.datasource.driverClassName=org.h2.Driver
task.datasource.url=jdbc:h2:tcp://localhost:9092/~/easy_task_db;MODE=MYSQL
task.datasource.username=sa
task.datasource.password=

#------  client options --------
task.log.packages=com.cehome.task.client.demo
task.log.path=/logs/easy_task/mvc_demo

  • 在spring mvc xml配置远程在线日志查看的controller。 不配这个controller则console无法在线连接到应用查看日志。

    <context:component-scan
            base-package="com.cehome.task.client.controller"/>
    <mvc:annotation-driven />
  • 开发任务插件

任务插件可以继承com.cehome.task.client.TimeTaskPlugin,由于执行方法是run()是固定的,在console配置任务信息时候就可以不配置。stop()方法会在点击停止任务时候触发,代码应用停止任务执行和释放必要的资源。

package com.cehome.task.client.demo;

import com.alibaba.fastjson.JSONObject;
import com.cehome.task.client.TimeTaskContext;
import com.cehome.task.client.TimeTaskPlugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.Inet4Address;

@Component
public class MvcDemoPlugin extends TimeTaskPlugin {
    private static final Logger logger = LoggerFactory.getLogger(MvcDemoPlugin.class);
    @Override
    public void run(TimeTaskContext context, JSONObject args) throws Exception {
        logger.info("plugin class name="+this);
        logger.info("task id="+context.getId()+"task name="+context.getName());
        logger.info("task run on ip="+ Inet4Address.getLocalHost().getHostAddress());
        logger.info("task run count="+context.getRunTimes());
    }

   @Override
    public void stop(TimeTaskContext context) throws Exception {
        logger.info("task "+context.getName()+" is stopped ");
    }
}


任务插件也可以是普通的spring bean,但在console配置任务信息时候,需要指定要执行的方法。

  • 在spring xml 加入插件的扫描路径
   <context:component-scan  base-package="com.cehome.task.client.demo"/>
  • 启动应用task-spring-mvc-client-demo
  • 访问console(不是mvc-demo)http://localhost:8080 (确保控制台是启动状态的),点击“添加”任务,
    应用选择“mvc-client-demo”;计划时间填5s(5秒);Bean名称跟上面开发插件一致,填写“mvcDemoPlugin”;其它必填字段自己随意。
  • 保存并关闭,点击“启动”,然后过10多秒钟点击“查看”日志,如果看到“task run……”日志,说明一切正常。

使用外部数据库

缺省的情况下,console会启动一个内部的数据库,生产环境建议用外部数据库。还是以H2数据库来说明:

  • 启动H2数据库

http://www.h2database.com/html/download.html 下载h2 数据库并解压,进入bin目录,执行命令启动数据库(9092是数据库访问端口)。

java -cp h2*.jar org.h2.tools.Server -tcpPort 9092 -tcpAllowOthers -webPort 8082 -webAllowOthers

  • 修改console或client数据库配置信息

task.datasource.driverClassName=org.h2.Driver
task.datasource.url=jdbc:h2:tcp://192.168.0.10:9092/~/easy_task_db;MODE=MYSQL
task.datasource.username=sa
task.datasource.password=

如果是console,可以修改task.h2.start=false 表示禁用内部数据库

task.h2.start=false

mysql数据库配置参考

task.datasource.driverClassName=com.mysql.jdbc.Driver
task.datasource.url=jdbc:mysql://192.168.0.13:3306/scheduler?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
task.datasource.username=root
task.datasource.password=123456

最佳实践建议

  • 独立mysql数据库
  • console 至少两个node
  • 若干应用,每个应用至少保持两个node
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
存储 监控 固态存储
【vSAN分布式存储服务器数据恢复】VMware vSphere vSAN 分布式存储虚拟化平台VMDK文件1KB问题数据恢复案例
在一例vSAN分布式存储故障中,因替换故障闪存盘后磁盘组失效,一台采用RAID0策略且未使用置备的虚拟机VMDK文件受损,仅余1KB大小。经分析发现,该VMDK文件与内部虚拟对象关联失效导致。恢复方案包括定位虚拟对象及组件的具体物理位置,解析分配空间,并手动重组RAID0结构以恢复数据。此案例强调了深入理解vSAN分布式存储机制的重要性,以及定制化数据恢复方案的有效性。
99 5
|
1月前
|
消息中间件 监控 数据可视化
Apache Airflow 开源最顶级的分布式工作流平台
Apache Airflow 是一个用于创作、调度和监控工作流的平台,通过将工作流定义为代码,实现更好的可维护性和协作性。Airflow 使用有向无环图(DAG)定义任务,支持动态生成、扩展和优雅的管道设计。其丰富的命令行工具和用户界面使得任务管理和监控更加便捷。适用于静态和缓慢变化的工作流,常用于数据处理。
Apache Airflow 开源最顶级的分布式工作流平台
|
5月前
|
机器学习/深度学习 人工智能 Shell
人工智能平台PAI操作报错合集之在分布式训练过程中遇到报错,是什么原因
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
4月前
|
消息中间件 Java Kafka
"Kafka快速上手:从环境搭建到Java Producer与Consumer实战,轻松掌握分布式流处理平台"
【8月更文挑战第10天】Apache Kafka作为分布式流处理平台的领头羊,凭借其高吞吐量、可扩展性和容错性,在大数据处理、实时日志收集及消息队列领域表现卓越。初学者需掌握Kafka基本概念与操作。Kafka的核心组件包括Producer(生产者)、Broker(服务器)和Consumer(消费者)。Producer发送消息到Topic,Broker负责存储与转发,Consumer则读取这些消息。首先确保已安装Java和Kafka,并启动服务。接着可通过命令行创建Topic,并使用提供的Java API实现Producer发送消息和Consumer读取消息的功能。
84 8
|
5月前
|
存储 缓存 分布式计算
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
|
5月前
|
NoSQL Java 调度
在Spring Boot中实现分布式任务调度
在Spring Boot中实现分布式任务调度
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能平台PAI产品使用合集之如何配置cluster系统自动生成分布式参数
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
5月前
|
机器学习/深度学习 存储 分布式计算
PAI机器学习平台如何进行分布式训练?
【7月更文挑战第1天】PAI机器学习平台如何进行分布式训练?
137 1
|
6月前
|
数据采集 JavaScript Java
一款分布式爬虫管理平台,支持多种语言和框架
项目介绍 Crawlab —— 一个基于 Golang 的分布式爬虫管理平台,支持Python、NodeJS、Go、Java、PHP 等多种编程语言以及多种爬虫框架。 主要功能: