响应式设计 手机网站,政务中心建设网站,建设工程查询市场价网站,6免费网站建站定时任务调度方案
随着系统规模的发展#xff0c;项目的组织结构以及架构越来越复杂#xff0c;业务覆盖的范围越来越广#xff0c;定时任务数量日益增多#xff0c;任务也变得越来越复杂#xff0c;尤其是为了满足在用户体量日历增大时#xff0c;系统能够稳定运行项目的组织结构以及架构越来越复杂业务覆盖的范围越来越广定时任务数量日益增多任务也变得越来越复杂尤其是为了满足在用户体量日历增大时系统能够稳定运行我们往往会扩充服务器做集群无论是传统垂直项目还是如今主流的分布式。那么对定时任务的要求也逐渐变高基于现在项目主流架构定时任务需满足一下要求 任务统一管理提供图形化界面对任务进行配置和调度。 保证任务调度的幂等性任务并发控制同一个任务在同一时间只能允许一个执行) 任务弹性扩容可根据繁忙情况动态增减服务器分摊压力对大任务进行分片处理。 任务依赖问题能够处理任务包含子任务的情况前一个完成后触发子任务执行。 支持多类型的任务支持Spring Bean、Shell等。 任务节点高可用任务节点异常或者繁忙时能够转移到其他节点执行。 调度中心高可用支持集群部署避免出现单点故障。 执行状态监控方便查看任务执行状态异常情况告警支持多渠道通知。
#. 发展史: 定时任务随着技术发展从单线程调度到多线程调度从单机部署到集群部署从独立执行到多任务协同执行。
1. Thread
通过线程休眠实现由JDK提供
private static int count 0;public static void main(String[] args) {Runnable runnable new Runnable() {Overridepublic void run() {while (count 8) {try {Thread.sleep(1000);System.out.printf(执行第%d 次\n, count);} catch (InterruptedException e) {e.printStackTrace();}}}};new Thread(runnable).start();
}2. 线程池
有延缓执行实现由JDK提供
private static int count 0;public static void main(String[] args) throws InterruptedException {for (int i 0; i 8; i) {ExecutorService executorService Executors.newSingleThreadScheduledExecutor();Runnable runnable new Runnable() {Overridepublic void run() {count;System.out.printf(执行从 %d 次\n, count);if (count 7) {System.exit(0);}}};// 也可以使用 ScheduledExecutorService.scheduleexecutorService.awaitTermination(1L, TimeUnit.SECONDS);executorService.execute(runnable);}
}3. Timer TimeTask
由JDK提供多用于移动端如安卓开发
private static int count 0;public static void main(String[] args) {TimerTask timerTask new TimerTask() {Overridepublic void run() {System.out.printf(执行第 %d 次\n, count);if (count 7) {System.exit(0);}}};Timer timer new Timer();timer.schedule(timerTask, 500, 500);
}4. Schedule
由Spring提供, 配合EnableScheduling 使用
Component
public class SpringScheduleTest {private static int count;Scheduled(cron 0/1 * * * * ?)public void testSchedule() {System.out.printf(执行第 %d 次\n, count);}
}cron 表达式秒-分-时-日-月-周-年
5.quartz
有maven独立依赖在SpringBoot2.0之后自带包
纯maven项目依赖!-- 核心包 --
dependencygroupIdorg.quartz-scheduler/groupIdartifactIdquartz/artifactIdversion2.3.0/version
/dependency!-- 工具包 --
dependencygroupIdorg.quartz-scheduler/groupIdartifactIdquartz-jobs/artifactIdversion2.3.0/version
/dependencySpringBoot2.0及上依赖dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-quartz/artifactId
/dependency测试类 Test.javapublic class Test {public static void main(String[] args) throws SchedulerException, ParseException {Scheduler factory StdSchedulerFactory.getDefaultScheduler();JobDataMap jobDataMap new JobDataMap();jobDataMap.put(tips, 去你大爷的);JobDetail jobDetail JobBuilder.newJob(QuartzJob.class).withIdentity(testJob, testJobGroup).setJobData(jobDataMap).build();Trigger trigger TriggerBuilder.newTrigger().withIdentity(testTrigger, testTriggerGroup).withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)).startNow().build();factory.scheduleJob(jobDetail, trigger);factory.start();}
}创建任务类 QuartzJob.javapublic class QuartzJob implements Job {public static int count;Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {JobDataMap jobDataMap jobExecutionContext.getMergedJobDataMap();String tips jobDataMap.getString(tips);System.out.printf(获取到参数%s\n, tips);System.out.printf(执行第%d 次\n, count);}
}6. Xxl-job
XXL-JOB 是一个轻量级分布式任务调度平台其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线开箱即用。 详细内容介绍请查看文档地址 创建库并创建表sql文件在项目目录下xxl-job-master/doc/db/tables_xxl_job.sql 注意它的数据库名是 xxl_job 如果不想创建新库而是导入到现有的库中需要进入sql文件中改名字。 运行项目xxl-job-admin 项目结构如下 修改mysql 连接配置如下 运行起来后 在浏览器访问http://localhost:8080/xxl-job-admin 默认账号admin 密码123456 成功登录后进入调度中心 注册任务执行器可以单独创建执行器服务也可集成到现有项目服务中去 以下为新建SpringBoot 项目为示例 创建SpringBoot 项目并添加依赖dependencygroupIdcom.xuxueli/groupIdartifactIdxxl-job-core/artifactIdversion2.3.1/version
/dependency在resources目录下创建application.properties文件(yaml文件也一样如果有就不用创建了)# 执行器所在的服务的运行端口 非执行器端口
server.port8081### xxl-job admin address list, such as http://address or http://address01,http://address02
# 注册地址 这个地址其实就是部署或者运行完xxl-job-admin调度中心的浏览器访问地址
xxl.job.admin.addresseshttp://127.0.0.1:8080/xxl-job-admin### xxl-job, access token
xxl.job.accessTokendefault_token### xxl-job executor appname
### 执行器名称需要配置到调度中心
xxl.job.executor.appnamexxl-job-executor
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address
### xxl-job executor server-info
xxl.job.executor.ip
# 这个端口是执行器端口 不是这个项目server.port 端口也不能一样否则会出现端口占用等错误信息
# 也就是说执行器项目部署或者运行起来会有两个端口如果是用docker部署注意两个端口都要映射到宿主机端口
xxl.job.executor.port9999
### xxl-job executor log-path
xxl.job.executor.logpath/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays30创建配置类 XxlJobConfig.javaConfiguration
public class XxlJobConfig {Value(${xxl.job.admin.addresses})private String adminAddresses;Value(${xxl.job.accessToken})private String accessToken;Value(${xxl.job.executor.appname})private String appname;Value(${xxl.job.executor.address})private String address;Value(${xxl.job.executor.ip})private String ip;Value(${xxl.job.executor.port})private int port;Value(${xxl.job.executor.logpath})private String logPath;Value(${xxl.job.executor.logretentiondays})private int logRetentionDays;Beanpublic XxlJobSpringExecutor xxlJobExecutor() {XxlJobSpringExecutor xxlJobSpringExecutor new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appname);xxlJobSpringExecutor.setAddress(address);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}
}创建任务 (Job)注意不同版本写法会有些不一样Component
public class SampleXxlJob {/*** 1、简单任务示例Bean模式*/XxlJob(demoJobHandler)public void demoJobHandler() throws Exception {XxlJobHelper.log(XXL-JOB, Hello World.);for (int i 0; i 5; i) {XxlJobHelper.log(beat at: i);TimeUnit.SECONDS.sleep(2);}XxlJobHelper.handleSuccess(XXL-JOB执行成功);}
}配置执行器 配置 成功 配置任务并执行 配置任务 执行一次 查看日志