为什么我们需要定时任务

很多业务场景需要我们某一特定的时刻去做某件任务,定时任务解决的就是这种业务场景。一般来说,系统可以使用消息传递代替部分定时任务,两者有很多相似之处,可以相互替换场景。如,上面发货成功发短信通知客户的业务场景,我们可以在发货成功后发送MQ消息到队列,然后去消费mq消息,发送短信。
但在某些场景下不能互换:

a)时间驱动/事件驱动:内部系统一般可以通过时间来驱动,但涉及到外部系统,则只能使用时间驱动。如怕取外部网站价格,每小时爬一次
b)批量处理/逐条处理:批量处理堆积的数据更加高效,在不需要实时性的情况下比消息中间件更有优势。而且有的业务逻辑只能批量处理。如移动每个月结算我们的话费
c)实时性/非实时性:消息中间件能够做到实时处理数据,但是有些情况下并不需要实时,比如:vip升级
d)系统内部/系统解耦:定时任务调度一般是在系统内部,而消息中间件可用于两个系统间

如果你的项目后期部署到集群环境下,如果不做处理,就会出现意想不到的问题,原因:由于我们项目同时部署在多台集群机器上,因此到达指定的定时时间时,多台机器上的定时器可能会同时启动,造成重复数据或者程序异常等问题

java有哪些定时任务的框架

单机

  • timer:是一个定时器类,通过该类可以为指定的定时任务进行配置。TimerTask类是一个定时任务类,该类实现了Runnable接口,缺点异常未检查会中止线程
  • ScheduledExecutorService:相对延迟或者周期作为定时任务调度,缺点没有绝对的日期或者时间
  • spring定时框架:配置简单功能较多,如果系统使用单机的话可以优先考虑spring定时器

分布

  • Quartz:Java事实上的定时任务标准。但Quartz关注点在于定时任务而非数据,并无一套根据数据处理而定制化的流程。虽然Quartz可以基于数据库实现作业的高可用,但缺少分布式并行调度的功能
  • TBSchedule:阿里早期开源的分布式任务调度系统。代码略陈旧,使用timer而非线程池执行任务调度。众所周知,timer在处理异常状况时是有缺陷的。而且TBSchedule作业类型较为单一,只能是获取/处理数据一种模式。还有就是文档缺失比较严重
  • elastic-job:当当开发的弹性分布式任务调度系统,功能丰富强大,采用zookeeper实现分布式协调,实现任务高可用以及分片,目前是版本2.15,并且可以支持云开发
  • Saturn:是唯品会自主研发的分布式的定时任务的调度平台,基于当当的elastic-job 版本1开发,并且可以很好的部署到docker容器上。
  • xxl-job: 是大众点评员工徐雪里于2015年发布的分布式任务调度平台,是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。

elastic-job的上次更新时间是两年前, 所以我们果断使用xxl-job了.

  1. 下载xxl-job的源码, http://www.xuxueli.com/xxl-job/

这次下载的是2.1.0的版本

  1. 解压源码, 导入源码到idea中去
  2. 执行数据库的文件

  1. 打开xxl-job-admin 项目,修改配置文件,修改application.properties中的数据库的配置信息, 然后启动xxl-job-admin 项目, 访问 http://localhost:8080/xxl-job-admin 就可以了, 默认登录账号 "admin/123456"
  2. 把xxl-job-core 项目达成一个jar 包, 放入到一个新的springboot 暂时名字叫做max-demo项目中去, 添加依赖到pom文件中去,
<!-- xxl-job-core --><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.1.0</version></dependency>
  1. 修改max-demo的配置文件
# web port
server.port=8081# log config
logging.config=classpath:logback.xml### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin### xxl-job executor address
xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.ip=
xxl.job.executor.port=9999### xxl-job, access token
xxl.job.accessToken=### xxl-job log path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler### xxl-job log retention days
xxl.job.executor.logretentiondays=-1
  1. 添加日志的配置文件: logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds"><contextName>logback</contextName><property name="log.path" value="/data/applogs/xxl-job/xxl-job-executor-sample-springboot.log"/><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern></rollingPolicy><encoder><pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n</pattern></encoder></appender><root level="info"><appender-ref ref="console"/><appender-ref ref="file"/></root></configuration>
  1. 添加配置文件:
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** xxl-job config** @author xuxueli 2017-04-28*/
@Configuration
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.executor.appname}")private String appName;@Value("${xxl.job.executor.ip}")private String ip;@Value("${xxl.job.executor.port}")private int port;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.logpath}")private String logPath;@Value("${xxl.job.executor.logretentiondays}")private int logRetentionDays;@Bean(initMethod = "start", destroyMethod = "destroy")public XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppName(appName);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}/*** 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;**      1、引入依赖:*          <dependency>*             <groupId>org.springframework.cloud</groupId>*             <artifactId>spring-cloud-commons</artifactId>*             <version>${version}</version>*         </dependency>**      2、配置文件,或者容器启动变量*          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'**      3、获取IP*          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();*/}
  1. 添加自己的定时任务处理类
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import org.springframework.stereotype.Component;/*** @author zk* @Description:* @date 2019-10-09 9:47*/
@Component
@JobHandler("myJobhandler2")
public class MyJobhandler extends IJobHandler {@Overridepublic ReturnT<String> execute(String param) throws Exception {System.out.println("这是自定义的第二个任务" + param);return ReturnT.SUCCESS;}
}
  1. 在网页上新建自己的定时任务.

分别是cron 表达式, jobhandker, 就是自定义的一个jobhandler, 名字对应就可以了.

执行就是把这个任务执行一次, 启动就是直接启动这个定时任务了, 根据cron表达式去执行.

调度中心集群

调度中心支持集群部署,提升调度系统容灾和可用性。

调度中心集群部署时,几点要求和建议:

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

在原来服务的基础上新建一个启动文件, 注释掉原项目中的端口信息,才用配置文件的形式.增加token,其他不改动.

就可以启动两个调度中心了.在任意一个调度中心上新建一个任务, 另一个都会有的.

执行器集群

执行器支持集群部署,提升调度系统可用性,同时提升任务处理能力。

执行器集群部署时,几点要求和建议:

  • 执行器回调地址(xxl.job.admin.addresses)需要保持一致;执行器根据该配置进行执行器自动注册等操作。
  • 同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表。

Web 的端口号和executor的端口号都不能重复.

修改配置文件,添加多个调度中心的地址, 以及token,修改端口号,注释掉端口号

新建一个springboot 启动类,然后启动两个服务,开始执行定时任务,执行了3次任务, 都发到同一个客户端执行了, 没有问题,在关闭了一个客户端之后,再次执行,任务失败. 过了一会,再执行,任务成功, 已经自动切换到另外一台应用上了,关闭一个调度中心也是没有问题的.

xxl-job分布式任务调度的使用相关推荐

  1. xxl子任务_阿里面试官:聊一下分布式任务调度有那些解决方案?

    作者:黄兆平 来源:http://blog.freshfood.cn/article/39 # 简介 随着系统规模的发展,定时任务数量日益增多,任务也变得越来越复杂,尤其是在分布式环境下,存在多个业务 ...

  2. xxl子任务_XXL-JOB v2.0.2,分布式任务调度平台 | 多项特性优化更新

    v2.0.2 Release Notes 1.底层通讯方案优化:升级较新版本xxl-rpc,由"JETTY"方案调整为"NETTY_HTTP"方案,执行器内嵌n ...

  3. xxl子任务_XXL-JOB v2.1.2 发布,分布式任务调度平台

    v2.1.2 Release Notes 1.方法任务支持:由原来基于JobHandler类任务开发方式,优化为支持基于方法的任务开发方式:因此,可以支持单个类中开发多个任务方法,进行类复用 @Xxl ...

  4. python建站部署_SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台...

    SpringBoot入门建站全系列(三十二)接入xxl-job分布式任务调度平台 一.概述 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源 ...

  5. python任务调度平台 界面_分布式任务调度平台XXL-JOB

    以前带我的人说过,最好的学习就是看官方文档,个人也有4个T的学习视频,但是会发现讲的都是入门,有的也比较浅. 官方文档比较官方,也比较权威,打开xxl-job的官网,写的贼详细,有些人喜欢收博客,不喜 ...

  6. 轻量级分布式任务调度平台 XXL-JOB

    From:https://www.cnblogs.com/xuxueli/p/5021979.html github 地址 及 中文文档地址:https://github.com/xuxueli/xx ...

  7. 分布式任务调度平台一站式讲解

    文章目录 一.传统的定时任务 1. 传统的定时任务存在那些缺点 2. 定时任务集群幂等性问题 二.传统定时任务的实现方案 2.1. 多线程 2.2. TimeTask 2.3. 线程池 2.4. Sp ...

  8. python任务调度平台 界面_分布式任务调度平台XXL-JOB搭建教程

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

  9. 分布式任务调度平台XXL-JOB搭建使用

    参考文档: xxl官方文档 https://www.xuxueli.com/xxl-job/ xxl搭建教程 https://www.cnblogs.com/ysocean/p/10541151.ht ...

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

    一.分布式任务调度概述 什么是任务调度平台 任务调度是指基于给定的时间点,给定的时间间隔又或者给定执行次数自动的执行任务.我们可以思考一下在以下场景中,我们应该怎么实现: 支付系统每天凌晨 1 点,进 ...

最新文章

  1. C++11 带来的新特性 (2)—— 统一初始化(Uniform Initialization)
  2. 30分钟,让你彻底明白Promise原理
  3. Spring Boot Admin 2 值得了解的新变化
  4. CentOS5.6下配置rsync内网同步数据到外网
  5. python 运行当前目录下的所有文件
  6. python入门if语句练习_python入门视频:09 if语句_练习.mp4
  7. python调用另一个.py文件中的类和函数
  8. CodeM资格赛 Round A 最长树链
  9. SpringCache实战遇坑
  10. 程序员这样面试,拿到offer的几率是非常大
  11. Codeforces 700 C. Break Up(Tarjan求桥)
  12. 软件测试 - 用例篇
  13. 【C语言】初学者写基础代码的基本步骤
  14. Office 之将 PPT 图片完美插入 Word
  15. if or函数套用_excel if函数和or函数结合使用的方法
  16. removeClass删除类名称
  17. 读书笔记:重来 Rework
  18. Oracle数据库操作:将有顿号的一条数据拆分为多行
  19. Flink 实时数仓伪分布虚拟机 (所有组件部署完成)
  20. 华为手机拍照那么厉害,为什么你却总拍不好?肯定是没调整这些设置

热门文章

  1. css动画效果网站集合
  2. 黑马程序员——java 泛型
  3. 在浏览器访问action中的方法(动态方法调用)
  4. 对51job网页招聘信息的简单爬取
  5. java 多线程抢票_多线程抢票详解
  6. 莫队算法小介绍——看似暴力的莫队算法
  7. Excel自动化教程之通过python将Excel与Word集成无缝生成自动报告
  8. 魔兽世界 圣骑士唯一的远程武器任务
  9. OpenCV 对象跟踪
  10. 手机内存卡照片丢失怎么恢复