栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

分布式任务调度平台一站式讲解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分布式任务调度平台一站式讲解

文章目录

一、传统的定时任务

1. 传统的定时任务存在那些缺点2. 定时任务集群幂等性问题 二、传统定时任务的实现方案

2.1. 多线程2.2. Timetask2.3. 线程池2.4. SpringBoot注解形式2.5. 基于Quartz 三、分布式任务调度平台架构设计原理

3.1. xxl-job项目模块讲解3.2. 最佳实战3.3. Xxl-job定时任务框架实现原理 四、常见面试题

4.1. XXL-JOB与ElasticJob区别之间区别4.2. 分布式任务调度分片集群策略原理4.3. 如何保证任务调度平台高可用问题
XXL开源社区

一、传统的定时任务 1. 传统的定时任务存在那些缺点

传统任务调度存在的缺陷

1.业务逻辑与定时任务逻辑放入在同一个Jar包中,如果定时任务逻辑挂了也会影响到业务逻辑;2.如果服务器集群的情况下,可能存在定时任务逻辑会重复触发执行;3.定时任务执行非常消耗cpu的资源,可能会影响到业务线程的执行 2. 定时任务集群幂等性问题

定时任务集群,如何保证定时任务幂等性问题
如何在集群中,保证我们的定时任务只会触发一次

1.将业务逻辑和定时任务逻辑完全分开部署,实现解耦、只对业务逻辑实现集群,不对我们的定时任务逻辑集群;—定时任务单机版本 缺点无法实现高可用的问题;2.对我们Jar包加上一个开关,项目启动的时候读取该开关 如果为true的情况下则加载定时任务类,否则情况下就不加载该定时任务类;–缺点无法实现高可用的问题;3.在数据库加上一个主键能够创建成功,则触发定时任务,否则就不触发定时任务, 高可用的问题;4.分布式锁实实现,只要jar能够拿到分布式锁就能够执行定时任务,否则情况下不执行;

总结:以上的方案都是属于规模比较小的项目,在微服务架构中应该采用分布式任务调度平台。

二、传统定时任务的实现方案

多线程形式、timetask、线程池、springboot注解形式、quartz

2.1. 多线程

基于多线程方式实现

package com.gblfy;

public class ThreadTask {

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                        System.out.println("定时任务触发...");
                    } catch (InterruptedException e) {

                    }
                }
            }
        }).start();
    }
}

2.2. Timetask
package com.gblfy;

import java.util.Timer;
import java.util.TimerTask;

public class TimerTaskDemo {
    public static void main(String[] args) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "定时任务触发");
            }
        };
        // 天数
        long delay = 0;
        // 耗秒数
        long period = 1000;
        new Timer().scheduleAtFixedRate(timerTask, delay, period);
    }
}

2.3. 线程池
package com.gblfy;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledExecutorServiceDemo {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("定时任务触发..");
            }
        };
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        scheduledExecutorService.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
    }
}

2.4. SpringBoot注解形式
package com.gblfy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class ScheduledTaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(ScheduledTaskApplication.class, args);
    }

}

package com.gblfy;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class UserScheduled {
    @Scheduled(cron = "0/1 * * * * *")
    public void taskUserScheduled() {
        System.out.println("定时任务触发...");
    }

}

2.5. 基于Quartz
  
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.quartz-scheduler
            quartz
            2.3.2
        
        
            org.quartz-scheduler
            quartz-jobs
            2.3.2
        

MyJob

package com.gblfy.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
       System.out.println("quartz MyJob date:" + System.currentTimeMillis());
   }
}

QuartzTest

package com.gblfy.job;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;

public class QuartzTest {
    public static void main(String[] args) throws SchedulerException {
        //1.创建Scheduler的工厂
        SchedulerFactory sf = new StdSchedulerFactory();
        //2.从工厂中获取调度器实例
        Scheduler scheduler = sf.getScheduler();


        //3.创建JobDetail
        JobDetail jb = JobBuilder.newJob(MyJob.class)
                .withDescription("this is a ram job") //job的描述
                .withIdentity("ramJob", "ramGroup") //job 的name和group
                .build();

        //任务运行的时间,SimpleSchedle类型触发器有效
        long time = System.currentTimeMillis() + 3 * 1000L; //3秒后启动任务
        Date statTime = new Date(time);

        //4.创建Trigger
        //使用SimpleScheduleBuilder或者CronScheduleBuilder
        Trigger t = TriggerBuilder.newTrigger()
                .withDescription("")
                .withIdentity("ramTrigger", "ramTriggerGroup")
                //.withSchedule(SimpleScheduleBuilder.simpleSchedule())
                .startAt(statTime)  //默认当前时间启动
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次
                .build();

        //5.注册任务和定时器
        scheduler.scheduleJob(jb, t);

        //6.启动 调度器
        scheduler.start();

    }
}
三、分布式任务调度平台架构设计原理 3.1. xxl-job项目模块讲解

xxl-job-admin—分布式任务调度中心平台
xxl-job-core—源码实现部分
xxl-job-executor-samples–执行器项目 定时任务模块项目

执行器模块:(注册中心)存放实际执行我们定时任务项目模块IP和端口信息;
分布式任务调度中心(Nginx):负责所有执行器执行定时任务的分配;

3.2. 最佳实战

定时任务与业务逻辑实现解耦,分开部署。
定时任务是一个单独的项目。
gblfy-member—会员服务接口
member-job----负责会员服务定时任务

3.3. Xxl-job定时任务框架实现原理
    当我们的定时任务模块项目启动的时候,会将该ip和端口信息注册到 定时任务注册中心上并发送rest请求需要将定时任务创建在任务调度中心中,关联执行器 定时任务模块实际执行ip和端口号码。创建定时任务会在xxl-job admin 调度中心中项目先触发,从执行器注册中心查找到执行器接口信息,采用路由策略(负载均衡算法)选择一个执行器(定时任务)地址 发送通知执行定时任务。

建议:配置定时任务规则的时候,建议提前5-10s;


常用分布式任务调度框架
Xxl-job、elasticjob、SpringAlibaba Cloud SchedulerX
XXL-Job Admin如何实现集群

四、常见面试题 4.1. XXL-JOB与ElasticJob区别之间区别

XXL-JOB内置定时任务调度中心,ElasticJob借助于zookeeper作为注册中心

4.2. 分布式任务调度分片集群策略原理

执行器集群部署时,任务路由策略选择”分片广播”情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;

“分片广播” 以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。

“分片广播” 和普通任务开发流程一致,不同之处在于可以获取分片参数,获取分片参数进行分片业务处理。

4.3. 如何保证任务调度平台高可用问题

调度中心集群(可选):
调度中心支持集群部署,提升调度系统容灾和可用性。

调度中心集群部署时,几点要求和建议:

1.DB配置保持一致;

2.集群机器时钟保持一致(单机集群忽视);

建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。

执行器集群(可选):
执行器支持集群部署,提升调度系统可用性,同时提升任务处理能力。
执行器集群部署时,几点要求和建议:

1.执行器回调地址(xxl.job.admin.addresses)需要保持一致;执行器根据该配置进行执行器自动注册等操作。2.同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778608.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号