• 【场景】java定时任务技术


    参考:https://developer.aliyun.com/article/882393

    1、java.util.TimerTask:

      所有的TimerTask是在同一个线程中串行执行,相互影响。也就是说,对于同一个Timer里的多个TimerTask任务,如果一个TimerTask任务在执行中,其它TimerTask即使到达执行的时间,也只能排队等待。如果有异常产生,线程将退出,整个定时任务就失败

    2、ScheduledExecutorService

      基于线程池设计的定时任务解决方案,每个调度任务都会分配到线程池中的一个线程去执行,解决Timer定时器无法并发执行的问题

    3、Springboot中@EnableScheduling + @Scheduled

    并行任务业务幂等解决方案:
      1、分布式锁

             1)基于DB、zookeeper: 有可能导致任务重复执行的。比如任务执行的非常快,A这台机器抢到锁,执行完任务后很快就释放锁了。B这台机器后抢锁,还是会抢到锁,再执行一遍任务。

        2)redis:抢锁支持过期时间,不用主动去释放锁,并且可以充分利用这个过期时间,解决任务执行过快释放锁导致任务重复执行的问题

      2、Quartz只需要定义了 Job(任务),Trigger(触发器)和Scheduler(调度器),即可实现一个定时调度能力。支持基于数据库的集群模式,可以做到任务幂等执行

          

    上面方案,在架构上问题是每次调度都需要抢锁,特别是使用DB和Zookeeper抢锁,性能会比较差,一旦任务量增加到一定的量,就会有比较明显的调度延时。
    
    还有一个痛点,就是业务想要修改调度配置,或者增加一个任务,得修改代码重新发布应用。

    开源任务调度中间件

      任务调度中间件,通过任务调度系统进行定,任务的创建、修改和调度,这其中国内最火的就是XXL-JOB和ElasticJob。

     1、ElasticJob

          一款基于Quartz开发,依赖Zookeeper作为注册中心、轻量级、无中心化的分布式任务调度框架,目前已经通过Apache开源。

      关于分片,失效转移:https://shardingsphere.apache.org/elasticjob/current/cn/features/elastic/

          ElasticJob相对于Quartz来说,从功能上最大的区别就是支持分片,可以将一个任务分片参数分发给不同的机器执行架构上最大的区别就是使用Zookeeper作为注册中心,不同的任务分配给不同的节点调度,不需要抢锁触发,性能上比Quartz上强大很多,架构如下:

         

      springboot配置文件

    elasticjob:
      regCenter:
        serverLists: localhost:2181
        namespace: elasticjob-lite-springboot
      jobs:
        simpleJob:
          elasticJobClass: org.apache.shardingsphere.elasticjob.lite.example.job.SpringBootSimpleJob
          cron: 0/5 * * * * ?
          timeZone: GMT+08:00
          shardingTotalCount: 3
          shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou
        scriptJob:
          elasticJobType: SCRIPT
          cron: 0/10 * * * * ?
          shardingTotalCount: 3
          props:
            script.command.line: "echo SCRIPT Job: "
        manualScriptJob:
          elasticJobType: SCRIPT
          jobBootstrapBeanName: manualScriptJobBean
          shardingTotalCount: 9
          props:
            script.command.line: "echo Manual SCRIPT Job: "
    View Code

      job实现:

    @Component
    public class SpringBootShardingJob implements SimpleJob {
        @Override
        public void execute(ShardingContext context) {
            System.out.println("分片总数="+context.getShardingTotalCount() + ", 分片号="+context.getShardingItem()
                + ", 分片参数="+context.getShardingParameter());
        }
    }
    View Code

      日志打印:

    分片总数=3, 分片号=0, 分片参数=Beijing
    分片总数=3, 分片号=1, 分片参数=Shanghai
    分片总数=3, 分片号=2, 分片参数=Guangzhou

      ElasticJob还提供了一个简单的UI,可以查看任务的列表,同时支持修改、触发、停止、生效、失效操作

    2、XXL-JOB

      是一个开箱即用的轻量级分布式任务调度系统,其核心设计目标是开发迅速、学习简单、轻量级、易扩展,在开源社区广泛流行。

      XXL-JOB是Master-Slave架构,Master负责任务的调度,Slave负责任务的执行,架构图如下

      

         XXL-JOB接入也很方便,不同于ElasticJob定义任务实现类,是通过@XxlJob 注解定义JobHandler

    @Component
    public class SampleXxlJob {
        private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
        /**
         * 1、简单任务示例(Bean模式)
         */
        @XxlJob("demoJobHandler")
        public ReturnT<String> demoJobHandler(String param) throws Exception {
            XxlJobLogger.log("XXL-JOB, Hello World.");
            for (int i = 0; i < 5; i++) {
                XxlJobLogger.log("beat at:" + i);
                TimeUnit.SECONDS.sleep(2);
            }
            return ReturnT.SUCCESS;
        }
        /**
         * 2、分片广播任务
         */
        @XxlJob("shardingJobHandler")
        public ReturnT<String> shardingJobHandler(String param) throws Exception {
            // 分片参数
            ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
            XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());
            // 业务逻辑
            for (int i = 0; i < shardingVO.getTotal(); i++) {
                if (i == shardingVO.getIndex()) {
                    XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
                } else {
                    XxlJobLogger.log("第 {} 片, 忽略", i);
                }
            }
            return ReturnT.SUCCESS;
        }
    }
    View Code

      XXL-JOB相较于ElasticJob,最大的特点就是功能比较丰富,可运维能力比较强,不但支持控制台动态创建任务,还有调度日志、运行报表等功能。

      

       XXL-JOB所有功能都依赖数据库,且调度中心不支持分布式架构,在任务量和调度量比较大的情况下,会有性能瓶颈。不过如果对任务量级、高可用、监控报警、可视化等没有过高要求的话,XXL-JOB基本可以满足定时任务的需求。

    
    
  • 相关阅读:
    (转载)SPSS之判别分析——决策树——以iris.sav为例
    (转载)SPSS之判别分析——以iris.sav为例
    python实现GA求二元函数最大值(来自知乎)
    (转载)Python在数学建模中的简单应用
    (转载)Python3 列表,数组,矩阵的相互转换
    【翻译自mos文章】在RHEL7/OL7上安装Oracle 12.1.0.2的server端或者client时,报须要&quot;compat-libstdc++&quot;包
    Material Design Support 8大控件介绍
    关于程序猿的技术发展讨论
    《C程序猿从校园到职场》带领大家从校园走向职场
    IE8下submit表单没反应
  • 原文地址:https://www.cnblogs.com/clarino/p/16157761.html
Copyright © 2020-2023  润新知