架构师系列- 定时任务(一)- 单机和分布式定时任务比较

这篇具有很好参考价值的文章主要介绍了架构师系列- 定时任务(一)- 单机和分布式定时任务比较。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

定时任务解决方案

定时任务概述

在很多应用中我们都是需要执行一些定时任务的,比如定时发送短信,定时统计数据,在实际使用中我们使用什么定时任务框架来实现我们的业务,定时任务使用中会遇到哪些坑,如何最大化的提高定时任务的性能。

我们这里主要介绍单机和分布式两大类的解决方案,并且简要介绍两类方案中的常见的应用组件或者框架的应用场景和基本的实现原理,重点分析下单机的定时任务的实现原理和优缺点。

为什么需要定时任务

下面是几个常见的定时任务场景

  1. 某系统凌晨要进行数据备份。
  2. 某媒体聚合平台,每 10 分钟动态抓取某某网站的数据为自己所用。
  3. 某博客平台,支持定时发送文章。
  4. 某基金平台,每晚定时计算用户当日收益情况并推送给用户最新的数据。

定时任务选型

单机定时任务

分布式的定时任务框架也是通过单机的原理而来,这里先介绍单机的几种实现方案,并且简单的对比分析

while+sleep方案

我们自己来实现一个定时任务,可以采用最简单的while循环加上一个sleep休眠方案,sleep是需要休眠的事件,下面就是我们事件的一个每隔5s休眠一次的案例

public class Scheduled1 {

    private static final long timeInterval = 5000;
    public static void main(String[] args) {

        new Thread(()->{
            while(true){
                System.out.println("定时任务每隔"+timeInterval+"毫秒执行一次");
                try {
                    Thread.sleep(timeInterval);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

 文章来源地址https://www.toymoban.com/news/detail-860015.html

实现还是很简单的,但是有一个问题,如果我们不仅仅只有定时5s的,还有3s、10s、20s的如何解决呢?不能每来一个不同的定时任务都需要新启动一个线程,这样会造成很多缺点:代码量巨大、开启线程很多占用内存、上下文切换频繁等

Timer定时器

定时计划任务功能在Java中主要使用的就是Timer对象,它在内部使用多线程的方式进行处理,所以它和多线程技术还是有非常大的关联的。在JDK中Timer类主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务,但封装任务的类却是TimerTask类

创建定时任务

通过继承 TimerTask 类 并实现 run() 方法来自定义要执行的任务

public class TimeTask1 extends TimerTask {
    @Override
    public void run() {
        System.out.println("定时任务运行了");
    }
}
调度定时任务

通过执行Timer.schedule(TimerTask task,Date time) 在执行时间运行任务

public class TimeScheduled {
    private static final long timeInterval = 5000;
    public static void main(String[] args) {
        Timer timer = new Timer();
        //延时10毫秒,每隔5s执行一次
        timer.schedule(new TimeTask1(),10,timeInterval);
    }
}

我们发现和我们第一个方案差不多,但是Timer的方案更加科学高效,我们发现他是可以支持延时执行,并且是可以支持定点执行

缺点

比如一个 Timer 一个线程,这就导致 Timer 的任务的执行只能串行执行,一个任务执行时间过长的话会影响其他任务。

线程池方式

ScheduledExecutorService 是一个接口,有多个实现类,比较常用的是 ScheduledThreadPoolExecutor ,

架构师系列- 定时任务(一)- 单机和分布式定时任务比较,c#,开发语言 

jdk自带的一个类是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响

代码案例
public class ScheduledExecutor {
    public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(() -> System.out.println("执行任务"), 10, 5, TimeUnit.SECONDS);
    }
}

不论是使用 Timer 还是 ScheduledExecutorService 都无法使用 Cron 表达式指定任务执行的具体时间。

springTask

SpringTask是Spring自主研发的轻量级定时任务工具,相比于Quartz更加简单方便,且不需要引入其他依赖即可使用

启动SpringTask

在配置类中添加一个@EnableScheduling注解即可开启SpringTask的定时任务

@SpringBootApplication
//启用定时任务的配置
@EnableScheduling
public class SpringTaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringTaskApplication.class);
    }
}
创建任务类

我们直接通过 Spring 提供的 @Scheduled 注解即可定义定时任务,非常方便!

@Component
public class SpringTask {
    @Scheduled(cron = "0/5 * * * * ?")
    public void testTask() throws InterruptedException {
        System.out.println("执行SpringTask任务,时间:" + LocalDateUtils.getLocalDateTimeStr());
    }
}

 

支持Cron表达式

Spring Task 支持 Cron 表达式

Cron 表达式主要用于定时作业(定时任务)系统定义执行时间或执行频率的表达式,非常厉害,你可以通过 Cron 表达式进行设置定时任务每天或者每个月什么时候执行等等操作

推荐一个在线 Cron 表达式生成器:在线Cron表达式生成器

优缺点
  • 优点:简单,轻量,支持 Cron 表达式
  • 缺点 :功能单一
分布式定时任务

上面提到的一些定时任务的解决方案都是在单机下执行的,适用于比较简单的定时任务场景比如每天凌晨备份一次数据

如果我们需要一些高级特性比如支持任务在分布式场景下的分片和高可用的话,我们就需要用到分布式任务调度框架了

Quartz

Quartz是一个完全由Java编写的开源任务调度的框架,通过触发器设置作业定时运行规则,控制作业的运行时间,其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性

 

quartz也是用的比较多的定时任务,很多分布式定时任务或者定制定时任务都是基于quartz来实现的,比如elastic-job就是借鉴quartz来实现的

优缺点
  • 优点:可以与 Spring 集成,并且支持动态添加任务和集群。
  • 缺点 :分布式支持不友好,没有内置 UI 管理控制台、使用麻烦(相比于其他同类型框架来说)
Elastic-Job

Elastic-job是当当网张亮主导开发的分布式任务调度框架,结合zookeeper技术解决quartz框架在分布式系统中重复的定时任务导致的不可预见的错误,功能丰富强大,实现任务高可用以及分片

Elastic-Job 中的定时调度都是由执行器自行触发,这种设计也被称为去中心化设计(调度和处理都是执行器单独完成)。

功能列表

ElasticJob 支持任务在分布式场景下的分片和高可用、任务可视化管理等功能

架构师系列- 定时任务(一)- 单机和分布式定时任务比较,c#,开发语言 

优缺点总结
  • 优点 :可以与 Spring 集成、支持分布式、支持集群、性能不错
  • 缺点 :依赖了额外的中间件比如 Zookeeper(复杂度增加,可靠性降低、维护成本变高)
XXL-JOB

XXL-JOB 于 2015 年开源,是一款优秀的轻量级分布式任务调度框架,支持任务可视化管理、弹性扩容缩容、任务失败重试和告警、任务分片等功能

功能列表

 架构师系列- 定时任务(一)- 单机和分布式定时任务比较,c#,开发语言

根据 XXL-JOB 官网介绍,其解决了很多 Quartz 的不足。

架构师系列- 定时任务(一)- 单机和分布式定时任务比较,c#,开发语言

不同于 Elastic-Job 的去中心化设计, XXL-JOB 的采用了中心化设计(调度中心调度多个执行器执行任务)

Quzrtz 类似 XXL-JOB 也是基于数据库锁调度任务,存在性能瓶颈,不过,一般在任务量不是特别大的情况下,没有什么影响的,可以满足绝大部分公司的要求。

优缺点总结:

  • 优点:开箱即用(学习成本比较低)、与 Spring 集成、支持分布式、支持集群、内置了 UI 管理控制台。
  • 缺点:不支持动态添加任务(如果一定想要动态创建任务也是支持的)。
组件对比

下图是常见的几个分布式定时任务的对比

feature quartz elastic-job-lite xxl-job
依赖 mysql jdk1.7+, zookeeper 3.4.6+ ,maven3.0.4+ mysql ,jdk1.7+ , maven3.0+
HA 多节点部署,通过竞争数据库锁来保证只有一个节点执行任务 通过zookeeper的注册与发现,可以动态的添加服务器。支持水平扩容 集群部署
任务分片 支持 支持
文档完善 完善 完善 完善
管理界面 支持 支持
难易程度 简单 较复杂 简单
公司 OpenSymphony 当当网 个人
高级功能 弹性扩容,多种作业模式,失效转移,运行状态收集,多线程处理数据,幂等性,容错处理,spring命名空间支持 弹性扩容,分片广播,故障转移,Rolling实时日志,GLUE(支持在线编辑代码,免发布),任务进度监控,任务依赖,数据加密,邮件报警,运行报表,国际化
缺点 没有管理界面,以及不支持任务分片等。不适用于分布式场景 需要引入zookeeper , mesos, 增加系统复杂度, 学习成本较高 调度中心通过获取 DB锁来保证集群中执行任务的唯一性, 如果短任务很多,随着调度中心集群数量增加,那么数据库的锁竞争会比较厉害,性能不好。
使用企业 大众化产品,对分布式调度要求不高的公司大面积使用 36氪,当当网,国美,金柚网,联想,唯品会,亚信,平安,猪八戒 大众点评,运满满,优信二手车,拍拍贷

 

到了这里,关于架构师系列- 定时任务(一)- 单机和分布式定时任务比较的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 分布式定时任务框架 PowerJob

    1.1 为什么需要使用定时任务调度 (1)时间驱动处理场景:整点发送优惠券,每天更新收益,每天刷新标签数据和人群数据。 (2)批量处理数据:按月批量统计报表数据,批量更新短信状态,实时性要求不高。 (3)异步执行解耦:活动状态刷新,异步执行离线查询,与内部

    2024年02月09日
    浏览(52)
  • Java | 一分钟掌握定时任务 | 9 - PowerJob分布式定时任务

    作者:Mars酱 声明:本文章由Mars酱整理编写,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我! 我们选择一套框架或者技术的时候,一定要知道它的特点和功能,不能为了(学习)技术而(选择)技术,那是对产品的不负责任。官方说有类似情况

    2024年01月24日
    浏览(42)
  • Java | 一分钟掌握定时任务 | 7 - ElasticJob分布式定时任务

    作者:Mars酱 声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我! ElasticJob 是面向互联网生态和海量任务的分布式调度解决方案。 它通过弹性调度、资源管控、以及任务治理的功能,打造一个适用于互联网场景的分

    2024年02月06日
    浏览(42)
  • 分布式定时任务调度框架Quartz

    Quartz是一个定时任务调度框架,比如你遇到这样的问题: 比如淘宝的待支付功能,后台会在你生成订单后24小时后,查看订单是否支付,未支付则取消订单 比如vip的每月自动续费功能 … 想定时在某个时间,去做某件事 Quartz是一套轻量级的任务调度框架,只需要定义了 Job(

    2024年02月04日
    浏览(37)
  • 使用shedlock实现分布式定时任务锁【防止task定时任务重复执行】

    第一步:引入shedlock相关依赖 ShedLock还可以使用Mongo,Redis,Hazelcast,ZooKeeper等外部存储进行协调,例如使用redis则引入下面的包 第二步:创建数据库表结构,数据库表的脚本如下: 第三步:添加shedlock配置类 (定时任务防重复执行的配置类) 第四步:在启动类上添加启动注

    2024年02月10日
    浏览(34)
  • 分布式定时任务调度xxl-job

    Quartz中最重要的三个对象:Job(作业)、Trigger(触发器)、Scheduler(调度器)。 xxl-job的调度原理:调度线程在一个while循环中不断地获取一定数量的即将触发的Trigger,拿到绑定的Job,包装成工作线程执行。 当然,不管在任何调度系统中,底层都是线程模型。如果要自己写一个

    2024年03月10日
    浏览(43)
  • springcloud:新一代分布式定时任务框架——PowerJob

    之前我们讲解过主流的分布式定时任务框架xxl-job,随着技术的迭代更新,更多的定时任务框架也开始出现,今天我们来看一看新一代的定时任务框架 PowerJob PowerJob是基于java开发的企业级的分布式任务调度平台,与xxl-job一样,基于web页面实现任务调度配置与记录,使用简单,

    2024年02月02日
    浏览(54)
  • 分布式定时任务-XXL-JOB-教程+实战

    1.定时任务认识 1.1.什么是定时任务 定时任务是按照指定时间周期运行任务。使用场景为在某个固定时间点执行,或者周期性的去执行某个任务,比如:每天晚上24点做数据汇总,定时发送短信等。 1.2.常见定时任务方案 While + Sleep : 通过循环加休眠的方式定时执行 Timer和Time

    2024年02月16日
    浏览(39)
  • Springboot 定时任务,分布式下幂等性如何解决

    在分布式环境下,定时任务的幂等性问题需要考虑多个节点之间的数据一致性和事务处理。 一种解决方法是使用分布式锁来保证同一时间只有一个节点能够执行该任务。具体实现可以使用Redis或Zookeeper等分布式协调工具提供的分布式锁功能。 另一种解决方法是使用消息队列来

    2024年02月11日
    浏览(23)
  • 基于Mongodb分布式锁简单实现,解决定时任务并发执行问题

    我们日常开发过程,会有一些定时任务的代码来统计一些系统运行数据,但是我们应用有需要部署多个实例,传统的通过配置文件来控制定时任务是否启动又太过繁琐,而且还经常出错,导致一些异常数据的产生 网上有很多分布式锁的实现方案,基于redis、zk、等有很多,但

    2023年04月18日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包