一、概述

什么是定时任务

  • 定时任务调度(开发) 相当于在某个时间段,进行一些任务操作。定时(在某个时间段进行操作假设2点)任务(需求) 调度(触发)
  • 案例:定时任务调度案例 ,我每天早上需要知道昨天一天的用户活跃量,写一个定时Job,每天早上9点钟,查询昨天UI天用户活月量,在以邮件方式发送到我的邮箱。
  • 定时任务应用场景:数据同步、交易信息、清楚用户信息、定期发送报表数据、活动推送
  • 引出问题:分布式任务调度平台分布式领域中服务器集群的话,如何保证定时Job幂等性

二、Java实现定时任务方式

2.1 Thread

  1. public class Demo01 {
  2. static long count = 0;
  3. public static void main(String[] args) {
  4. Runnable runnable = new Runnable() {
  5. @Override
  6. public void run() {
  7. while (true) {
  8. try {
  9. Thread.sleep(1000);
  10. count++;
  11. System.out.println(count);
  12. } catch (Exception e) {
  13. // TODO: handle exception
  14. }
  15. }
  16. }
  17. };
  18. Thread thread = new Thread(runnable);
  19. thread.start();
  20. }
  21. }

2.2 TimerTask

  1. /**
  2. * 使用TimerTask类实现定时任务
  3. */
  4. public class Demo02 {
  5. static long count = 0;
  6. public static void main(String[] args) {
  7. TimerTask timerTask = new TimerTask() {
  8. @Override
  9. public void run() {
  10. count++;
  11. System.out.println(count);
  12. }
  13. };
  14. Timer timer = new Timer();
  15. // 天数
  16. long delay = 0;
  17. // 秒数
  18. long period = 1000;
  19. timer.scheduleAtFixedRate(timerTask, delay, period);
  20. }
  21. }

2.3 ScheduledExecutorService

使用ScheduledExecutorService是从Java
JavaSE5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式。

  1. public class Demo003 {
  2. public static void main(String[] args) {
  3. Runnable runnable = new Runnable() {
  4. public void run() {
  5. // task to run goes here
  6. System.out.println("Hello !!");
  7. }
  8. };
  9. ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
  10. // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
  11. service.scheduleAtFixedRate(runnable, 1, 1, TimeUnit.SECONDS);
  12. }
  13. }

2.4 Quartz

引入maven依赖

  1. <dependencies>
  2. <!-- quartz -->
  3. <dependency>
  4. <groupId>org.quartz-scheduler</groupId>
  5. <artifactId>quartz</artifactId>
  6. <version>2.2.1</version>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.quartz-scheduler</groupId>
  10. <artifactId>quartz-jobs</artifactId>
  11. <version>2.2.1</version>
  12. </dependency>
  13. </dependencies>

任务调度类

  1. public class MyJob implements Job {
  2. public void execute(JobExecutionContext context) throws JobExecutionException {
  3. System.out.println("quartz MyJob date:" + new Date().getTime());
  4. }
  5. }

启动类

  1. //1.创建Scheduler的工厂
  2. SchedulerFactory sf = new StdSchedulerFactory();
  3. //2.从工厂中获取调度器实例
  4. Scheduler scheduler = sf.getScheduler();
  5. //3.创建JobDetail
  6. JobDetail jb = JobBuilder.newJob(MyJob.class)
  7. .withDescription("this is a ram job") //job的描述
  8. .withIdentity("ramJob", "ramGroup") //job 的name和group
  9. .build();
  10. //任务运行的时间,SimpleSchedle类型触发器有效
  11. long time= System.currentTimeMillis() + 3*1000L; //3秒后启动任务
  12. Date statTime = new Date(time);
  13. //4.创建Trigger
  14. //使用SimpleScheduleBuilder或者CronScheduleBuilder
  15. Trigger t = TriggerBuilder.newTrigger()
  16. .withDescription("")
  17. .withIdentity("ramTrigger", "ramTriggerGroup")
  18. //.withSchedule(SimpleScheduleBuilder.simpleSchedule())
  19. .startAt(statTime) //默认当前时间启动
  20. .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次
  21. .build();
  22. //5.注册任务和定时器
  23. scheduler.scheduleJob(jb, t);
  24. //6.启动 调度器
  25. scheduler.start();

Quartz表达式

  1. http://cron.qqe2.com/

三、分布式情况下定时任务会出现哪些问题?

分布式集群的情况下,怎么保证定时任务不被重复执行

  1. 定时任务和业务代码存放在同一个jvm (小项目)
  2. 大型互联网公司定时任务代码执行与业务执行代码服务器都是分开,都是独立的jvm。
  3. 定时任务服务器是否需要考虑高并发?同一时间点执行多个任务间隔场景是不需要,同时场景可能会发生高并发
  4. 如果在高并发的情况下,定时Job宕机之后应该如何处理? (单台节点) 使用心跳检测监控自动重启、补偿机制(每个任务打一个小标记) 定时任务在执行代码的时候中间突然报错了,使用日志记录错误,跳过继续执行,在使用定时JOb扫描日志错误记录,进行补偿信息。定时]ob在执行的时候,导致整个Job异常结束掉,发送邮件通知给运维人员

传统定时任务与分布式定时任务区别
传统定时任务特征:单一(没有集群)

四、分布式定时任务解决方案

  1. 使用zookeeper实现分布式锁 缺点(需要创建临时节点、和事件通知不易于扩展)
  2. 使用配置文件做一个开关 缺点发布后,需要重启,设置一个开启任务的开关,将其中一台服务器中设置为true,代表开启任务,其他的服务器设置为false,此种方式如果设置为true的服务器宕机了,任务就失效了。(不推荐)
  3. 数据库唯一约束,缺点效率低 (不推荐)
  4. 使用分布式任务调度平台 XXLJOB、Elastric-Job、TBSchedule

五、XXLJOB介绍

5.1 分布式任务调度平台能够帮我们实现那些事情

  1. 支持Job集群(前提保证幂等性问题) Job负载均衡轮训机制
  2. 支持Job补偿如果Job执行失败的话,会自动实现重试机制,如果重启多次还是失败的话,发送邮件通知给运维人员。
  3. 支持Job日志记录
  4. 动态配置定时规则传统定时JOb触发规则都是写死,采用动态配置Job规则

5.2 XXLJOB GitHub

XXLJOB项目及文档


XX-JOB

5.3 原理

  • XXL-Job原理:执行器、任务管理

    • 执行器表达意思:定时Job实际执行的服务地址
    • 任务管表达意思:配置定时任务规则、路由策略、允许模式、等。

步骤

  • ① 部署: xxl-job-admin 作为注册中心
  • ② 创建执行器(具体调度地址) 可以支持集群
  • ③ 配置文件需要填写xxl-job注册中心地址
  • ④ 每个具体执行job服务器需要创建一个netty连接端口号
  • ⑤ 需要执行job的任务类,集成IJobHandler抽象类注册到job容器中
  • ⑥ Execute方法中编写具体job任务

5.4 SpringBoot整合XXLJob

配置文件信息

application.properties

  1. # web port
  2. server.port=8081
  3. # log config
  4. logging.config=classpath:logback.xml
  5. ### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
  6. xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
  7. ### xxl-job executor address
  8. xxl.job.executor.appname=text-job
  9. xxl.job.executor.ip=
  10. xxl.job.executor.port=9999
  11. ### xxl-job, access token
  12. xxl.job.accessToken=
  13. ### xxl-job log path
  14. xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
  15. ### xxl-job log retention days
  16. xxl.job.executor.logretentiondays=-1

配置XxlJobConfig

  1. @Configuration
  2. @ComponentScan(basePackages = "com.xxl.job.executor.service.jobhandler")
  3. public class XxlJobConfig {
  4. private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
  5. @Value("${xxl.job.admin.addresses}")
  6. private String adminAddresses;
  7. @Value("${xxl.job.executor.appname}")
  8. private String appName;
  9. @Value("${xxl.job.executor.ip}")
  10. private String ip;
  11. @Value("${xxl.job.executor.port}")
  12. private int port;
  13. @Value("${xxl.job.accessToken}")
  14. private String accessToken;
  15. @Value("${xxl.job.executor.logpath}")
  16. private String logPath;
  17. @Value("${xxl.job.executor.logretentiondays}")
  18. private int logRetentionDays;
  19. @Bean(initMethod = "start", destroyMethod = "destroy")
  20. public XxlJobExecutor xxlJobExecutor() {
  21. logger.info(">>>>>>>>>>> xxl-job config init.");
  22. XxlJobExecutor xxlJobExecutor = new XxlJobExecutor();
  23. xxlJobExecutor.setAdminAddresses(adminAddresses);
  24. xxlJobExecutor.setAppName(appName);
  25. xxlJobExecutor.setIp(ip);
  26. xxlJobExecutor.setPort(port);
  27. xxlJobExecutor.setAccessToken(accessToken);
  28. xxlJobExecutor.setLogPath(logPath);
  29. xxlJobExecutor.setLogRetentionDays(logRetentionDays);
  30. return xxlJobExecutor;
  31. }
  32. }

创建handler接口

  1. @JobHandler("demoJobHandler")
  2. @Component
  3. public class DemoHandler extends IJobHandler {
  4. @Value("${server.port}")
  5. private String serverPort;
  6. @Override
  7. public ReturnT<String> execute(String param) throws Exception {
  8. System.out.println("######端口号:serverPort" + serverPort + "###定时Job开始执行啦!!!!######");
  9. return SUCCESS;
  10. }
  11. }

5.5 调度中心集群

  如果xx-job admin 平台挂掉的话,会导致任务无法执行,所以调度中心也需要部署集群,调度中心支持集群部署,提升调度系统容灾和可用性。调度中心集群部署时,几点要求和建议:

  1. DB配置保持一致;
  2. 登陆账号配置保持一致;
  3. 群机器时钟保持一致(单机集群忽视);
  4. 建议:推荐通过nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回调配置、调用API服务等操作均通过该域名进行。


xxl-job集群原理

Nginx配置信息

  1. upstream backServer{
  2. server 127.0.0.1:8080 weight=1;
  3. server 127.0.0.1:8081 weight=1;
  4. }
  5. server {
  6. listen 80;
  7. server_name 127.0.0.1 ;
  8. #charset koi8-r;
  9. #access_log logs/host.access.log main;
  10. location / {
  11. proxy_pass http://backServer;
  12. index index.html index.htm;
  13. }
  14. error_page 500 502 503 504 /50x.html;
  15. location = /50x.html {
  16. root html;
  17. }
  18. }

【Distributed】分布式任务调度平台的更多相关文章

  1. 分布式任务调度平台XXL-JOB快速使用与问题总结

    1.XXL-JOB简介 XXL-JOB is a lightweight distributed task scheduling framework. It's core design goal is ...

  2. 转载《分布式任务调度平台XXL-JOB》

    <分布式任务调度平台XXL-JOB>       博文转自 https://www.cnblogs.com/xuxueli/p/5021979.html 一.简介 1.1 概述 XXL-J ...

  3. 分布式任务调度平台XXL-JOB

    <分布式任务调度平台XXL-JOB>       一.简介 1.1 概述 XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并 ...

  4. 分布式任务调度平台XXL-JOB搭建教程

    关于分布式任务调度平台XXL-JOB,其实作者 许雪里 在其发布的中文教程中已经介绍的很清楚了,这里我就不做过多的介绍了,关于其搭建教程,本人依照其文档搭建起来基本上也没遇到啥问题,这里通过博客的形式 ...

  5. XXL-JOB分布式任务调度平台安装与部署

    配XXL-JOB分布式任务调度平台安装与部署

  6. 宜信开源|分布式任务调度平台SIA-TASK的架构设计与运行流程

    一.分布式任务调度的背景 无论是互联网应用或者企业级应用,都充斥着大量的批处理任务.我们常常需要一些任务调度系统来帮助解决问题.随着微服务化架构的逐步演进,单体架构逐渐演变为分布式.微服务架构.在此背 ...

  7. 分布式任务调度平台XXL-JOB学习笔记一

    分布式任务调度平台XXL-JOB学习笔记一 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司线上产品线,开箱即用.码云地址 ...

  8. 一文读懂分布式任务调度平台XXL-JOB

    本文主要介绍分布式任务调度平台XXL-JOB(v2.1.0版本),包括功能特性.实现原理.优缺点.同类框架比较等 基本介绍 项目开发中,常常以下场景需要分布式任务调度: 同一服务多个实例的任务存在互斥 ...

  9. 分布式任务调度平台XXL-JOB快速搭建教程

    1. XXL-JOB简介 XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并接入多家公司线上产品线,开箱即用.它的有两个核心模块,一个模块叫做 ...

随机推荐

  1. 123457123456#0#-----com.twoapp.jingPinYinYu01----儿童学英语jiemei

    com.twoapp.jingPinYinYu01----儿童学英语jiemei

  2. html页面设置自动刷新

    在中添加如下: <meta HTTP-EQUIV="REFRESH" CONTENT="1"> 其中CONTENT对应刷新的间隔时间,这里为1秒. ...

  3. sersync参数说明

    -v, --verbose 详细模式输出-q, --quiet 精简输出模式-c, --checksum 打开校验开关,强制对文件传输进行校验-a, --archive 归档模式,表示以递归方式传输文 ...

  4. python介绍,计算机组成。内存分布,进制,操作系统介绍

    学习小方法 ​三个W一个Hwwwh:what(是什么) why(为什么) where(怎么用) how(如何用) 来思考知识点多练,多写,多敲代码增加熟练度与代码量​ Python 是一门面向后台的编 ...

  5. python选课系统demo的小练习

    #简化选课系统代码:先登陆,然后判断身份并实例化,根据身份对应的类,让用户选择 class Manager: operate_dict=[ ('创造学生账号',"creat_student& ...

  6. 性能优化-service进程防杀

    service作为后台服务,其重要性不言而喻,但很多时候service会被杀死,从而失去了我们原本想要其发挥的作用,在这种情况下我们该如何确保我们的service不被杀死就是本节需要讨论的内容了 se ...

  7. 【leetcode算法-中等】3. 无重复字符的最长字串

    [题目描述] 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 " ...

  8. v-bind 绑定属性

    与mustache相区别,他是对内容(content内部)进行修改的.v-bind的语法糖写法是   : v-bind 动态绑定class属性:v-bind:class="对象名" ...

  9. [转帖]Oracle报错ORA-26563--当重命名表时碰到物化视图

    Oracle报错ORA-26563--当重命名表时碰到物化视图 https://www.toutiao.com/i6739137279115133447/ 原创 波波说运维 2019-09-26 00 ...

  10. 1.1Spring Boot 环境配置和常用注解

    Spring Boot常用注解:@Service: 注解在类上,表示这是一个业务层bean@Controller:注解在类上,表示这是一个控制层bean@Repository: 注解在类上,表示这是一 ...