首页 > 其他分享 >分布式任务调度

分布式任务调度

时间:2023-04-30 15:44:06浏览次数:42  
标签:任务调度 调度 Timer 任务 执行 public 分布式

  1、什么是任务调度?   我们可以先思考一下下面业务场景的解决方案:

  • 某电商系统需要在每天上午 10点,下午3点,晚上8点发放一批优惠券。
  • 某银行系统需要在信用卡到期还款日的前三天进行短信提醒。
  • 某财务系统需要在每天凌晨 0:10结算前一天的财务数据,统计汇总。
  • 12306 会根据车次的不同,而设置某几个时间点进行分批放票。
  • 某网站为了实现天气实时展示,每隔 5分钟就去天气服务器获取最新的实时天气信息。
以上场景就是任务调度所需要解决的问题。   任务调度是指系统为了自动完成特定任务,在约定的特定时刻去执行任务的过程。有了任务调度即可解放更多的人力由系统自动去执行任务。   2、任务调度如何实现?   (1)多线程方式实现 可以开启一个线程,每sleep一段时间,就去检查是否已到预期执行时间。以下代码简单实现了任务调度的功能:
public static void main(String[] args) {   
   //任务执行间隔时间  
    final long timeInterval = 1000;
    Runnable runnable = new Runnable() {
        public void run() {
            while (true) {
                //TODO:something
                try {
                    Thread.sleep(timeInterval);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    Thread thread = new Thread(runnable);
    thread.start();
}

上面的代码实现了按一定的间隔时间执行任务调度的功能。Jdk也提供了相关支持,如Timer、ScheduledExecutor。

(2)Timer方式实现:
public static void main(String[] args) {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            //TODO:something
        }
    }, 1000, 2000);  //1秒后开始调度,每2秒执行一次
}
Timer 的优点在于简单易用,每个Timer对应一个线程,因此可以同时启动多个Timer并行执行多个任务,同一个Timer中的任务是串行执行。但是存在缺点,jdk1.5后并不再使用。   (3)ScheduledExecutor方式实现:
public static void main(String [] agrs) {
    ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
    service.scheduleAtFixedRate(
    new Runnable() {
        @Override
        public void run() {
            //TODO:something
            System.out.println("todo something");
        }
    }, 1, 2, TimeUnit.SECONDS);
}
Java 5 推出了基于线程池设计的 ScheduledExecutor,其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。Timer 和 ScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求。比如,设置每月第一天凌晨1点执行任务、复杂调度任务的管理、任务间传递数据等等。   (4)第三方Quartz方式实现: Quartz 是一个功能强大的任务调度框架,它可以满足更多更复杂的调度需求,Quartz 设计的核心类包括Scheduler, Job 以及 Trigger。其中,Job 负责定义需要执行的任务,Trigger 负责设置调度策略,Scheduler 将二者组装在一起,并触发任务开始执行。Quartz支持简单的按时间间隔调度、还支持按日历调度方式,通过设置CronTrigger表达式(包括:秒、分、时、日、月、周、年)进行任务调度。
public static void main(String [] agrs) throws SchedulerException {
    //创建一个Scheduler
    SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    Scheduler scheduler = schedulerFactory.getScheduler();
    //创建JobDetail
    JobBuilder jobDetailBuilder = JobBuilder.newJob(MyJob.class);
    jobDetailBuilder.withIdentity("jobName","jobGroupName");
    JobDetail jobDetail = jobDetailBuilder.build();
    //创建触发的CronTrigger 支持按日历调度
    CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("triggerName", "triggerGroupName")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        //创建触发的SimpleTrigger 简单的间隔调度
        /*SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("triggerName","triggerGroupName")
                .startNow()
                .withSchedule(SimpleScheduleBuilder
                        .simpleSchedule()
                        .withIntervalInSeconds(2)
                        .repeatForever())
                .build();*/
    scheduler.scheduleJob(jobDetail,trigger);
    scheduler.start();
}
public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext){
        System.out.println("todo something");
    }
}
  3、什么是分布式任务调度  通常任务调度的程序是集成在应用中的,比如:优惠券服务中包括了定时发放优惠券的的调度程序,结算服务中包括了定期生成报表的任务调度程序,由于采用分布式架构,一个服务往往会部署多个冗余实例来运行我们的业务,在这种分布式系统环境下运行任务调度,我们称之为分布式任务调度,如下图: 分布式调度要实现的目标是不管是任务调度程序集成在应用程序中,还是单独构建的任务调度系统,如果采用分布式调度任务的方式就相当于将任务调度程序分布式构建,这样就可以具有分布式系统的特点,并且提高任务的调度处理能力: 1、并行任务调度:并行任务调度实现靠多线程,如果有大量任务需要调度,此时光靠多线程就会有瓶颈了,因为一台计算机CPU的处理能力是有限的。如果将任务调度程序分布式部署,每个结点还可以部署为集群,这样就可以让多台计算机共同去完成任务调度,我们可以将任务分割为若干个分片,由不同的实例并行执行,来提高任务调度的处理效率。 2、高可用:若某一个实例宕机,不影响其他实例来执行任务。 3、弹性扩容:当集群中增加实例就可以提高并执行任务的处理效率。 4、任务管理与监测:对系统中存在的所有定时任务进行统一的管理及监测。让开发人员及运维人员能够时刻了解任务执行情况,从而做出快速的应急处理响应。 5、避免任务重复执行:当任务调度以集群方式部署,同一个任务调度可能会执行多次,比如在上面提到的电商系统中到点发优惠券的例子,就会发放多次优惠券,对公司造成很多损失,所以我们需要控制相同的任务在多个运行实例上只执行一次,考虑采用下边的方法:
  • 分布式锁,多个实例在任务执行前首先需要获取锁,如果获取失败那么久证明有其他服务已经再运行,如果获取成功那么证明没有服务在运行定时任务,那么就可以执行。
  • ZooKeeper 选举,利用ZooKeeper对Leader实例执行定时任务,有其他业务已经使用了ZK,那么执行定时任务的时候判断自己是否是Leader,如果不是则不执行,如果是则执行业务逻辑,这样也能达到我们的目的。
 

标签:任务调度,调度,Timer,任务,执行,public,分布式
From: https://www.cnblogs.com/liujiarui/p/17260104.html

相关文章

  • openGauss分布式安装_搭建_快速部署openGauss3.0.0分布式(openGauss课程)
    一、opengauss的背景和行业现状2022年,七大openGauss商业版发布,是基于openGauss3.0推出商业发行版目前海量数据库Vastbase表现最佳,一直是TOP1作者认为之所以海量数据库Vastbase目前无法被同行超越,和各家研发实力和技术背景有关 众所周知,opengauss起源于postgre......
  • 二、分布式基础概念--谷粒商城
    1.微服务服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTPAPI。这些服务围绕业务能力来构建,并通过完全自动化部署机制来独立部署。这些服务使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中......
  • SequoiaDB分布式数据库2023.4月刊
    本月看点速览赋能产业升级,荣获新睿之星聚焦金融,进一步探索非结构化数据价值释放再获肯定,入选2023年中国最佳信创厂商入围名单青杉计划2023已开启,一起攀登更高的“杉” 赋能产业升级,荣获新睿之星4月18日,2023年第九届广州国际投资年会在广州白云国际会议中心成功举办。会中......
  • 大数据学习初级入门教程(十六) —— Hadoop 3.x 完全分布式集群的安装、启动和测试
    好久没用Hadoop集群了,参考以前写的《大数据学习初级入门教程(一)——Hadoop2.x完全分布式集群的安装、启动和测试_孟郎郎的博客》和《大数据学习初级入门教程(十二)——Hadoop2.x集群和Zookeeper3.x集群做集成_孟郎郎的博客-》,下载了目前官网最新的版本 hadoop-3.3.5再......
  • Zabbix 3.0 alpha6企业级分布式监控系统发布
    Zabbix企业级分布式监控系统发布了3.0第六个alpha版本,目前Zabbix3.0还处在内测阶段,官方不建议大家慎重使用。BUT,目前我的alpha5版本运行良好。胆量大的同学不妨升级到最新版本。备注:zabbix升级是一个不可逆的过程,还请慎重!zabbix3.0alpha6如下更新:[ZBXNEXT-3073]实现公共与私有sc......
  • redisson 分布式锁
    @RequestMapping(value="/testLock",method=RequestMethod.POST)publicBaseResponse<Boolean>testLock(@RequestBodyTestLockRequesttestLockRequest){RLockrLock=null;booleanisLocked=false;try{......
  • 织密“安全云网”,天翼云探索构建分布式多场景云服务稳定性保障体系!
    近日,中国信息通信研究院(以下简称“中国信通院”)主办,混沌工程实验室承办的信息通信领域系统稳定性保障沙龙·北京站成功举办。沙龙以“共筑数字免疫韧性长城,助力信息通信行业稳定安全运行”为主题,旨在促进信息通信领域系统稳定性保障技术交流,推动信息通信领域稳定安全运行水平提升,......
  • 织密“安全云网”,天翼云探索构建分布式多场景云服务稳定性保障体系!
    近日,中国信息通信研究院(以下简称“中国信通院”)主办,混沌工程实验室承办的信息通信领域系统稳定性保障沙龙·北京站成功举办。沙龙以“共筑数字免疫韧性长城,助力信息通信行业稳定安全运行”为主题,旨在促进信息通信领域系统稳定性保障技术交流,推动信息通信领域稳定安全运行水平提升,加......
  • redis完成分布式锁
    1.正文1.Redis完成分布式锁2.redis的面试题。2.缓存当执行增删改操纵时必须保证缓存和数据库数据一致性。---删除缓存@OverridepublicDeptinsert(Deptdept){inti=deptMapper.insert(dept);returndept;}@Overridep......
  • 分布式编译系统的搭建
    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。作者:dan文章来源:GreatSQL社区原创由于MySQL源码编译单机耗费的时间过于长,最近MySQL变成8.0.27以后编译时间明显更耗时了,并且办公室内有多余的空闲......