如何自己设计一个定时任务分布式调度器

Java如何实现定时任务? 这篇文章主要讲了什么是定时任务、为什么要用定时任务、在Java领域中如果有定时任务相关的需求可以用什么来实现、分布式定时任务的基础知识以及如何接入XXL-JOB相信大家对分布式定时任务框架有了个基本的了解,如果感兴趣可以挑个开源框架去学学,在此我向大家推荐一个架构学习交流圈。交流学习伪鑫539413949(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像httpshttpshttpshttpshttpshttpshttpshttpshttpshttpshttps。... 阅读详情

为什么要使用分布式调度器

分布式调度器主要应用于系统中一些任务定时调度处理。通常我们设计一个定时任务,最简单的就是直接使用@scheduled注解配置好定时任务,这样开发工作也简单。但是也许会有一种情况,如果发生在生产环境上,需要不重启就去变更定时任务时间,或者可能由于某些原因我们需要关闭某个定时任务,那么这时候就无法做到动态化。分布式调度器就能很好的解决这些疑难杂症。

有的人可能会问:现在开源的调度器也有一些很流行的,比如xxl-job,为什么还要自己设计一套。其实我们也不能说开源的设计不好,原因是它的功能太完善,如果要用好还要有人专门运维处理,功能过于强大,大部分功能都是鸡肋,所以自研一套简单的调度服务有些时候还是很有必要的。

分布式调度流程

首先分布式调度器需要依赖数据库配置,主要配置调度服务接口和调度时间。通过调度服务集群获取数据库配置,解析完需要进行调度的任务,由于是job服务的一个集群(也可以单机部署)所以也要考虑到加锁,防止多个job服务同时对一个任务多次调度。最终job服务将解析完的服务接口,检测到触发时间点就对应用服务接口发起任务调度。

分布式调度细节设计分析

数据库设计

job_info表设计:主要记录一些job任务的配置,下面分析一下主要字段:

  • job_cron:定时任务触发时间配置
  • config_id:关联调度任务服务接口配置主键
  • execute_timeout:任务调度超时时间配置,防止调度时间过长无结果
  • execute_fail_retry_count:如果任务调度失败重试次数
  • job_status:调度任务状态开关配置
  • trigger_last_time:最后一次调度时间
  • trigger_next_time:下一次执行时间

job_config表设计:主要配置一些任务对应需要调度的服务接口信息。

  • execute_servier:所需调度的应用服务
  • execute_method:调度应用服务接口
  • execute_param:调度参数配置
  • service_type:服务类型(GET/POST)

     

job服务调度流程设计

  • 读取配置:首先job服务需要不断的读取数据库配置,从而得知有哪一些任务需要进行调度。可以通过一个while循环加上休眠一段时间不断读取配置,下面就用简短的伪代码做个思路分析:
while(true) {
    // PRE_READ_TIME每次刷新时间间隔
    TimeUnit.MILLISECONDS.sleep(PRE_READ_TIME - System.currentTimeMillis() % 1000);
    // 读取配置,给定一个时间,获取这段时间内要执行调度的任务以及初次配置的任务trigger_next_time=0
    List<JobInfo> jobInfos = jobInfoMapper.select(time);
    // 循环对任务一一进行解析
    // 1.job应用对获取到的任务进行加锁,防止job集群其他服务同时调用,如果确定只会有单机部署可不加锁
    int resultCount = jobInfoMapper.updateByOptimisticLock(jobInfo);
    // 2.加锁成功继续执行下一步,对首次配置的任务(trigger_next_time=0)需要获取job_cron进行解析,计算出真实的下次执行时间trigger_next_time
     refreshNextValidTime(jobInfo, new Date(nowTime));
    // 3.即将要执行的任务加入队列
   checkHighFrequency(jobInfo, nowTime);
}

private void checkHighFrequency(JobInfo jobInfo, Long nowTime) throws ParseException {
    // PRE_READ_TIME = 5000,即提前预留5秒,将任务加入队列
    if (jobInfo.getTriggerNextTime() < (nowTime + PRE_READ_TIME)) {
        // 将任务放入待执行队列
        triggerPoolHelper.triggerJob(jobInfo, jobInfo.getTriggerNextTime() - nowTime);
        // 任务加入队列后,再次更新计算下次调度job的时间
        refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
        // 判断是否是超高频繁任务,即调度周期小于5s一次
        checkHighFrequency(jobInfo, nowTime);
    }
}
// 计算下次执行时间
private void refreshNextValidTime(JobInfo jobInfo, Date fromTime) throws ParseException {
    // 时间表达式转换计算下次触发时间
    Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(fromTime);
    if (nextValidTime != null) {
        jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
        jobInfo.setTriggerNextTime(nextValidTime.getTime());
    }
}

  • 线程池队列执行任务调度
public void triggerJob(JobInfo jobInfo, long delay) {
    JobInfo copyOf = new JobInfo();
    BeanUtils.copyProperties(jobInfo, copyOf);
    JobTriggerThread triggerThread = new JobTriggerThread(copyOf, tinyJobExecutor.get(jobInfo.getJobType()));
    // 小于0说明是延期的任务,立即执行
    if (delay <= 0) {
        // 加入线程池
        triggerPool.execute(triggerThread);
    }
    // 大于0说明还未到调度时间,延迟调度
    else {
        triggerPool.schedule(triggerThread, delay, TimeUnit.MILLISECONDS);
    }
}

  • 任务调度流程:SpringCloud服务使用DiscoveryClient,根据job_config表配置的服务名获取集群服务列表,再根据随机(或自定义算法)计算获取一个服务实例,用该实例创建请求并发起服务接口调用,最终再根据调用结果进行日志记录,以及失败后续是否进行重试处理。
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances(jobConfig.getExecuteService());
// 随机获取服务列表(可自定义算法)
ServiceInstance serviceInstance = getRandomInstrance(serviceInstanceList);
CloseableHttpClient httpClient = HttpClients.createDefault();
// 创建请求
HttpPost httpPost = new HttpPost(serviceInstance.getUri() + "/" + jobConfig.getExecuteMethod() + "?" + jobConfig.getExecuteParam());
// http发起调用
CloseableHttpResponse response = httpClient.execute(httpPost);

案例配置说明

  • 添加两个定时任务配置,此配置如有需要也可开发个简单的页面方便配置添加与更改。

  • 定时任务对应的调度服务接口配置

根据以上的配置,定时刷新获取任务列表,任务首次配置trigger_next_time=0,需解析成具体执行时间点,任务调度判断该时间点是否达到可执行时间,在达到指定时间点job服务将对该接口发起调用并记录调度日志。

总结

使用分布式调度器能够很好的管理我们的定时任务接口,开发人员也只需专注开发业务接口,让业务与配置完全分离。定时配置还可以根据业务场景统一进行时间协调管理,以免在有些时间点多任务同时处理,可以将时间配置的分散点以减轻CPU的压力。如果系统业务量少,定时任务也不多的情况也没必要多浪费时间开发一个调度系统。

C语言实现调度器(附完整源码) 阅读详情

相关推荐

Spring schedule定时任务前台界面配置源代码-可直接打开看效果

附件解压之后得到名为"schedule"的目录,双击里面的schedule.html,再单击浏览器弹出框“允许阻止的内容”,可以看到下面的效果。 界面采用bootstrap和JEasyUI技术实现,提供三种任务运行规则:一次性、周期性、自定义 1、一次性(i:立即运行;ii:在规定的时间刻运行) 2、周期性(i:按小时;ii:按天 iii:按周; iv:按月(日);v: 按月(星期) ) 3、自定义(自定义功能,用户可以在前台随意定制执行计划,只要符合spring schedule cronExpression语法) 亮点: i:日期选择功能使用JEasyUI的datetime,并在选择框上加了限制,不能选择早于当前的日期 ii:时间选择功能使用JEasyUI的spinner实现 iii: 自定义功能用户可以随意定制执行计划 iv:采用bootstrap的pills实现tab(选项卡)功能,界面友好 另:内附schdule Spring后台核心代码供后台开发参考

分布式任务调度,定时任务的处理方案

4.复制配置文件,文件在xxl-job项目的 xxl-job-2.3.1\xxl-job-executor-samples\xxl-job-executor-sample-springboot\src\main\java\com\xxl\job\executor\core\config 的XxlJobConfig。这个命令将会创建一个名为 xxl-job-admin 的容器,并且将容器的 8080 端口映射到宿主机的 8080 端口,使得我们可以通过浏览器访问到 XXL-Job 的管理界面。

qq_56533553的博客 2769

从零开始:Doherty功率放大器的ADS仿真实践指南

本文详细介绍了Doherty功率放大器在ADS中的仿真设计流程,从基础原理到实际工程应用。通过负载调制技术,Doherty结构显著提高了功率放大器的效率,特别适合处理高峰均比信号。文章包含ADS环境搭建、对称与非对称设计、常见问题调试等实用内容,为射频工程师提供全面的实践指南。

weixin_29313547的博客 693

Quartz + SpringBoot 实现定时任务(多任务,多执行时间)代码模板(转)

quartz 是一款开源且丰富特性的Java任务调度库,用于实现任务调度和定时任务。它支持各种任务类型和灵活的配置选项,具备作业持久化、集群和分布式调度、错误处理和重试机制等功能。Quartz被广泛应用于各种应用程序中,提供可靠和灵活的任务调度解决方案。

朱塔山的博客 2734

轴承寿命预测实战:手把手教你用IEEE PHM2012数据集训练模型(附Python代码)

本文详细介绍了如何利用IEEE PHM2012数据集构建轴承剩余寿命预测模型,从数据预处理、特征工程到LSTM模型训练与部署,提供了完整的Python代码实现。通过实战案例,帮助读者掌握预测性维护中的关键技术,提升工业设备的运行安全与效率。

weixin_29186249的博客 313

K型热电偶分度表读取方法

K型热电偶分度表读取方法

guaizaiguaizai的博客 5918

一款你不得不了解的轻量级分布式任务调度系统

一款你不得不了解的轻量级分布式任务调度系统! github地址:CronMan 简介 CronMan是一款轻量级的分布式任务调度系统。随着微服务化架构的逐步演进,单体架构逐渐演变为分布式、微服务架构,相应的也需要一个分布式任务调度系统来管理分布式架构中的定时任务。 已有的分布式任务调度系统如:Saturn、elastic-job、xxl-job都是非常优秀的开源作品,为了学习与交流,我设计了一款轻量级的分布式任务调度系统CronMan,具有一些崭新的特性如:任务编排、任务结果传递、高可用、任务幂等性触发等

weixin_43614115的博客 6450

U盘安装单系统ubuntu10.04之全过程&拔掉U盘后系统无法启动

借助U盘把电脑装成ubuntu单系统之过程记录,以及遇到拔掉U盘后系统无法启动问题,电脑就显示: Non-System disk or disk error, replace and strike any key when ready

CXHPLY的专栏 8682

Golang:gocron定时任务管理系统的安装与使用

简介gocron是一个使用Go语言开发的轻量级定时任务集中调度和管理系统, 用于替代Linux-crontab文档。

彭世瑜的博客 2941

《数学建模与数学实验》第5版 线性规划 习题3.4

1. 某鸡场有1000只鸡,用动物饲料和谷物混合喂养. 2. 某工厂用A1,A2两台机床加工B1,B2,B3三种不同零件. 3. 某工厂利用两种原料甲、乙生产$A_1、A_2、A_3$三种产品. 4. 每班的护士在值班开始时向病房报到,连续工作8个小时. 5. 某工厂生产 A1 、A2 两种型号的产品 6. 有两个煤厂A,B 7. 某工厂制造三种产品,生产这三种产品需要三种资源 8. 已知某工厂计划生产1,2,3三种产品,各产品需要在ABC设备加工。...

hexiaosi_的博客 2万+

MTK Linux Charger驱动分析(二) - power_supply_core.c

的核心作用可以概括为:提供统一的电源管理框架;管理电源设备注册、属性访问、事件通知;封装sysfs 接口和 uevent 通知,屏蔽硬件细节;驱动开发者只需要实现,不关心底层通知和接口细节。简单来说,它是电源子系统的“大脑和中枢”,具体的电池/充电器只是“信息源”。

iTom1900 1490

面试官问,怎么实现一个定时任务调度器?如果是分布式下的呢?

首先要思考一下通用的定时器大概包含哪些要素?首先,应该听过Quartz,Spring Schedule 等框架;往分布式研究,又有 SchedulerX,ElasticJob 等分布式任务调度。那么往底层实现看,又有多种定时器实现方案的原理、工作效率、数据结构等等可以进行思考。 那么抽象来说,定时器大概包含如下属性,判断一个任务是否到期,基本会采用轮询的方式,** 每隔一个时间片 ** 去检查 ** 最近的任务 ** 是否到期,并且,在 NewTask 和 Cancel 的行为发生之后,任务调度策略也会出

Javaesandyou的博客 2643

Arch Linux 命令大全,值得收藏!

Arch Linux 是一款轻量级、高度可定制的 Linux 发行版,以其简洁和强大的特性深受高级用户喜爱。但对于新手来说,完全掌握 Arch Linux 的操作需要时间和实践。本文将为您详细介绍常用的 Arch Linux 命令,涵盖系统管理、文件操作、用户管理、软件安装与管理、网络配置和磁盘管理等内容,帮助您更高效地使用 Arch Linux。

网络技术联盟站 975

ruoyi-vue-pro定时任务:Quartz调度器与分布式任务

在企业级应用开发中,定时任务是不可或缺的核心功能。ruoyi-vue-pro基于Quartz调度器框架,提供了强大而灵活的定时任务解决方案,支持分布式部署和高可用性。本文将深入解析其架构设计、核心实现和使用方法。 ## 定时任务架构概览 ruoyi-vue-pro的定时任务模块采用分层架构设计,核心组件包括: ```mermaid classDiagram class JobHand...

gitblog_00332的博客 611

网络安全系列-四十三:使用Suricata分析恶意流量pcap文件

本文基于[网络安全系列-三十六:使用Suricata IDS分析pcap文件]和 [网络安全系列-四十二: Suricata之rulesets的激活、更新及动态加载]的基础上,使用suricata针对包含恶意流量的pcap文件进行分析,触发事件告警,并对suricata输出的日志进行逐个分析,让你掌握针对恶意流量的分析步骤,及怎么查看suricata输出的日志。

penriver的博客 2889

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Xxl-Job分布式定时任务

XXL-JOB是一个分布式任务调度平台,是一个分布式定时任务的解决方案,作者的名字叫许雪里。解决问题:在分布式环境下,传统的定时任务,如SpringTask、Timer等,存在定时任务重复执行,无法追踪任务执行结果等,使用Xxl-job可以有效避免在分布式环境下,定时任务出现的各类问题,同时还支持任务结果日志,数据统计,预警邮件等功能。xxl-job: 一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。

m0_51607909的博客 6531

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

分布式定时任务调度框架

分布式定时任务框架的对比

代码让AI扣 9600

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

lamp-cloud分布式定时任务详解:基于lamp-job的调度器实现

在微服务架构中,**分布式定时任务**是确保系统自动化和高效运行的关键组件。lamp-cloud项目通过集成**lamp-job调度器**,为开发者提供了一套完整的分布式定时任务解决方案。前100字内,我们重点介绍lamp-job调度器的核心功能和优势。 ## 🚀 什么是lamp-job分布式调度器? **lamp-job**是基于xxl-job进行功能增强的**分布式定时任务调度器**,它

gitblog_00236的博客 900

分布式定时任务原理以及解决方案-指定时间执行定时任务

分布式定时任务原理以及实现 一、单机指定时间执行定时任务实现方式 Timer运行机制 ScheduledThreadPoolExecutor的运行机制 原理图 Leader/Follower模式正在上传…重新上传取消 Timer和ScheduledThreadPoolExucutor区别 Timer是基于绝对时间,ScheduledThreadPoolExucutor基于相对时间 Timer是单线程,ScheduledThreadPoolExucutor是多线程 Timer运行发

后端研发工程师Marion的博客 8307

【青训营】分布式定时任务简述

定时任务是指系统为了自动完成特定任务,实时、延时、周期性完成任务调度的过程。分布式定时任务是把分散的、可靠性差的定时任务纳入统一平台,并且实现集群管理调度和分布式部署的一种定时任务管理方式定时任务:特定时间触发,比如今天15:06执行延时任务:延时触发,比如10s后执行周期任务:固定周期时间,或者固定频率周期调度触发,比如每天12点或者每隔5s执行按照执行方式分类单机任务:随机触发一台机器执行任务,适合计算量小、并发度低的任务广播任务:将一个命令广播到所有机器上执行,比如一起清理日志。

weixin_45434953的博客 701

如何用Celery实现精准定时任务?深度解析Beat调度器的5个高级用法

掌握Celery精准定时任务的实现方法,解决python celery异步任务中的调度难题。深入解析Beat调度器的5种高级用法,涵盖周期任务配置、时区处理、动态调度等核心技巧,提升任务执行效率与系统可靠性,值得收藏。

PixelIsle的博客 1107

企业级运营定时任务分发设计

定时任务在我们日常开发中是一个常见的场景。当下的分布式定时任务的开源项目也较多,每种定时器都有着它的一些优势和不足,但无论哪种本质上是为了实现业务的目的而去实施,因此鉴于在工作中有过相关的开发,以及取得不错的效果,想把自己的一些东西沉淀出来分享给大家,特写了这篇文章。本文也将主要介绍相关的一些定时器设计的一些方案和具体架构流程。本文将主要符合业务场景为:时间粒度最小为秒级,针对于某些大人群的一些定时任务。

gokkxxx的博客 1758

分布式定时任务框架说明

分布式定时任务框架说明

天涯的博客 3143

当事件调度器遇见微服务:分布式环境下的MySQL定时任务实践

本文探讨了在微服务架构下如何有效利用MySQL事件调度器实现分布式定时任务。通过分析幂等性设计、主从同步策略及与Kubernetes CronJob的协同方案,提供了在分布式环境中使用MySQL事件调度器的最佳实践,帮助开发者解决重复执行、资源竞争等核心挑战。

s8t9u0v1w的博客 890
上一篇: java Spring菜鸟教程,只需一篇文章吃透Java多线程技术
下一篇: 点赞3K的《SpringBoot手册》,让你轻松吊打面试官
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值