java - 分布式任务调度(Elastic - job ,xxl - job)

传统的任务调度

  • 常用的工具

    -简介优点缺点
    Timerjava.utilTimer 工具类简单易用单线程来调度,任务间相互挤占影响
    Spring-Taskspring3.0以后引入的定时任务工具,相当于轻量级的Quartz用法简单,只需要引入Spring的包任务执行默认单线程(可配置为多线程)
    任务调度为同步模式,上一调度对下一调度 有影响
    Quartzjava事实上的定时任务标准采用多线程异步调度
    满足更多更复杂的调度需要
    配置使用稍复杂
  • cron表达式

    字段允许值允许的特殊符号
    0~59 整数, - * /
    0~59 整数, - * /
    小时0~23 整数, - * /
    日期0~31 整数, - * / ? L W C
    月份0~12 整数, - * /
    星期1~7 整数, - * / ? L C #
    年(可选,留空)1970 ~, - * /

    *:表示匹配该域的任意值
    ?: 只能在日期和星期两个域使用,表示匹配域的任意值
    -:表示范围
    /:表示起始时间开始触发,然后每隔固定时间触发一次
    ,:表示列出枚举值
    L : 表示最后的时间,只能在日期和星期两个域使用
    w : 表示有效工作日(周一到周五),只能在日期域中使用
    LW : LW两个字符可以连用,表示某个月最后一个工作日,即最后一个星期五
    #: 用于确定每个月第几个星期几,只能出现在星期域中。例如 4#2,表示某月的第二个星期三

  • Timer的简单使用

    package com.example.taskschedule.timer;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerTest {
    
        static int i = 1;
    
        public static void main(String[] args) {
            Timer timer = new Timer();
            //延迟3秒后,执行一次
            timer.schedule(add(), 3000);
            
            //延迟1秒后,每隔3秒执行一次
            timer.schedule(add(), 1000, 3000);
        }
    
    
        public static TimerTask add() {
            return new TimerTask() {
                @Override
                public void run() {
                    System.out.println(i++);
                }
            };
        }
    
    }
    
    
  • spring-task的简单使用

    package com.example.taskschedule.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
    
    /**
     * 配置Spring-Task的线程池
     *   如果不配置线程池Spring-Task的任务调度将默认以单线程的方式运行
     *   @EnableScheduling  启用Scheduling
     *
     */
    @Configuration
    @EnableScheduling
    public class SpringTaskConfig {
    
        @Bean
        public ThreadPoolTaskScheduler SpringTask() {
            ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
            taskScheduler.setPoolSize(10);
            taskScheduler.setThreadNamePrefix("Spring-Task-Thread");
            return taskScheduler;
        }
    
    
    }
    
    package com.example.taskschedule.springtask;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class SpringTaskTest {
    
    
        //上一个任务结束到下一个任务开始的时间间隔为固定的1秒,任务的执行总是要先等到上一个任务的执行结束
        @Scheduled(fixedDelay = 1000)
        public void add() {
            System.out.println("当前线程A:" + Thread.currentThread().getId());
        }
    
    
        //每间隔1秒钟就会执行任务(如果任务执行的时间超过1秒,则下一个任务在上一个任务结束之后立即执行)
        @Scheduled(fixedRate = 1000)
        public void add1() {
            System.out.println("当前线程B:" + Thread.currentThread().getId());
        }
    
        //第一次执行的任务将会延迟3秒钟后才会启动
        @Scheduled(fixedDelay = 1000, initialDelay = 3000)
        public void add2() {
            System.out.println("当前线程C:" + Thread.currentThread().getId());
        }
    
    
        //Cron表达式,每个月的15号上午10点15开始执行任务
        @Scheduled(cron = "0 15 10 15 * ?")
        public void add3() {
            System.out.println("当前线程D:" + Thread.currentThread().getId());
        }
    
    }
    
  • Quartz的简单使用

       敬请期待
    

传统定时任务存在的问题

  • 业务耦合
    如果需要修改定时任务时间,就需要重新部署整个应用将会导致整个应用停止一段时间

  • 单点风险
    所有调度任务都在单台服务器上执行,当任务执行节点出现问题时,整个定时任务全部终止

  • 资源分配不均衡
    随着业务越来越多,相应的定时任务也会增多,单台服务器执行任务的压力会越来越大

分布式任务调度

  • 常用方案

    -简介优点缺点
    Elastic - job当当提供的开源分布式调度工具,封装Quartz,使用Zookeeper 协调任务通过zookeeper来动态扩容,分片和弹性扩容性能好,业务量大的时候也能非常好的调度使用和配置复杂,任务控制不灵活
    xxl - job"调度中心"基于集群Quartz实现并支持集群部署.
    任务分布式执行,任务‘’执行器‘’支持集群部署
    原理简单、实现简洁、对任务控制更灵活调度中心通过DB锁保证一致性,执行器的扩展,会增大DB压力
  • Elastic - job的使用

     #引入jar
     <dependency>
           <groupId>com.github.yinjihuan</groupId>
           <artifactId>elastic-job-spring-boot-starter</artifactId>
           <version>1.0.2</version>
      </dependency>
    
    #添加配置mave库地址-(elastic-job-spring-boot-starter 在中央maven库不存在)
    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
    
    # 添加elastic-job的zk注册中心配置
    elastic.job.zk.serverLists=127.0.0.1:2181
    elastic.job.zk.namespace=enjoy_elastic
    
    #Job类
    
    #name 任务名称,cron 定时规则
    #shardingItemParameters 分片参数,shardingTotalCount 分片数
    #listener 自定义-ElasticJob作业监听器. 默认 "" (不监听)
    #jobExceptionHandler 自定义-ElasticJob异常处理器. 默认DefaultJobExceptionHandler
    #overwrite 是否允许客户端规则参数覆盖注册中心.  默认 false 不允许
    	
    @ElasticJobConf(name = "ElasticJob", cron = "0/5 * * * * ?"
            , shardingItemParameters = "0=beijing,1=shanghai", shardingTotalCount = 2
            , listener = "com.example.taskschedule.elasticjob.ElasticJobMsgListener"
            , jobExceptionHandler = "com.example.taskschedule.elasticjob.ElasticJobExceptionHandler"
            , overwrite = true)
    public class ElasticJob implements SimpleJob {
    
        @Override
        public void execute(ShardingContext shardingContext) {
            System.out.println(Thread.currentThread().getName() + " ,当前分片参数=" + shardingContext.getShardingParameter());
            int i = 1 / 0;
        }
    
    }
    
    /**
     * 自定义 - ElasticJob作业监听器
     */
    public class ElasticJobMsgListener implements ElasticJobListener {
    
        @Override
        public void beforeJobExecuted(ShardingContexts shardingContexts) {
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            String msg = date + " 【任务开始执行-" + shardingContexts.getJobName() + "】";
            System.out.println("before: " + msg);
        }
    
        @Override
        public void afterJobExecuted(ShardingContexts shardingContexts) {
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            String msg = date + " 【任务执行结束-" + shardingContexts.getJobName() + "】";
            System.out.println("after: " + msg);
        }
    }
    
    /**
     * 自定义-ElasticJob异常处理器
     */
    @Slf4j
    public class ElasticJobExceptionHandler implements JobExceptionHandler {
    
        @Override
        public void handleException(String jobName, Throwable throwable) {
            log.error(String.format("Job '%s' exception occur in job processing", jobName), throwable);
            System.out.println("exception:【" + jobName + "】任务异常。" + throwable.getMessage());
        }
    
    }
    
  • xxl - job的使用

     敬请期待
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: xxl-jobelastic-job是两个不同的分布式任务调度框架。 xxl-job是一个国内开源的分布式任务调度平台,提供了任务调度、任务执行、任务监控、报警等功能,支持分布式部署,适用于大规模分布式任务调度场景。 elastic-job是一个国内开源的分布式任务调度框架,提供了分布式任务调度分布式数据流处理、分布式数据分片等功能,支持多种任务类型,适用于大规模分布式任务调度和数据处理场景。 ### 回答2: xxl-jobelastic-job是两种开源分布式任务调度框架,它们都能够让用户方便地进行任务调度并且提高任务的执行效率。 首先,xxl-job是一款比较受欢迎的国内开源调度框架,它支持多种任务调度模式,包括定时调度、固定频率调度、Cron表达式调度等。同时, xxl-job还提供了一些方便的特性,如任务日志和执行器心跳检测等。作为一款较为成熟的调度框架,xxl-job还提供了完整的Web控制台,用户可以方便地添加和管理任务,并且在控制台上查看任务的执行情况和任务日志。 而elastic-job则是由阿里巴巴公司开源的任务调度框架,它提供了分布式任务调度能力和高可用的服务治理特性。相比于xxl-jobelastic-job提供了更加灵活的任务调度能力,并且支持分布式任务的动态扩容,使得用户可以更加自由地进行任务调度。 该框架还提供了多种任务类型的支持,如简单任务、数据流任务、脚本任务等,使得用户能够更加方便地进行任务调度。类似于xxl-jobelastic-job同样提供了完善的控制台,用户可以在控制台上管理和监控任务的执行情况和任务日志。 虽然xxl-jobelastic-job都是比较成熟的任务调度框架,但它们在一些细节和特性上还存在差异。因此,用户需要根据自己的需求选择合适的框架,以实现最优的任务调度效果。 ### 回答3: xxl-jobelastic-job是两个广泛应用于分布式任务调度的开源项目。下面将从以下几个方面详细介绍xxl-jobelastic-job。 1.架构设计 xxl-job采用了任务调度器和任务执行器分离的架构设计,任务调度器通过定时发送调度请求到任务队列,任务执行器则通过轮询任务队列获取任务并执行。这种分离的设计方式使得任务调度和执行更加灵活,降低了系统的耦合度。同时,xxl-job还支持多种任务执行模式,包括BEAN模式、CMD模式以及GLUE模式。GLUE模式是一种基于注解和反射机制实现动态调用的方式,灵活性非常高,适用于各种场景。 elastic-job同样采用了分布式的架构设计,并且支持多种任务执行模式,包括在摆渡任务之间均匀地分配作业实例的AVG模式、指定分片序列号执行作业的EXECUTION模式以及动态调度分片和扩容缩容的SCRIPT模式。 2.可扩展性 xxl-job支持多种任务调度器集群模式,包括单机调度器、集群调度器、注册中心调度器和多级调度器。在高并发、大流量、高任务密度的场景下,可以灵活地配置多个任务调度器实例组成集群,提高系统的性能和可靠性。 elastic-job支持分片调度,可以根据作业实例和分片进行分布式并发执行,充分利用资源并提高效率。同时,elastic-job还支持作业分片的动态扩容、缩容,可以根据实际业务变化进行弹性调度。 3.可视化管理 xxl-job提供了可视化的任务管理界面,包括任务列表、任务日志、任务监控等模块,方便管理人员快速了解任务执行情况和进行操作。同时,xxl-job还提供了一套完整的API,方便二次开发和集成。 elastic-job同样提供了易于使用的控制台,支持多维度的作业监控、配置修改、状态管理等功能,降低了系统的运维成本。 总之,xxl-jobelastic-job都是优秀的分布式任务调度框架,在不同场景下都有着良好的应用效果。其中,xxl-job更注重任务分发和管理,适合于一些企业级业务场景;而elastic-job更注重分片执行和弹性调度,适合于一些需要高并发和动态调度的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值