xxl-job Vs ElasticJob,谁牛?

news/2024/7/5 2:05:40

欢迎关注方志朋的博客,回复”666“获面试宝典

  • 1. xxl-job

  • 2. 运行 xxl-job

  • 3. 开发定时任务

    • 3.1 项目创建及配置

    • 3.2 定时任务开发方式

  • 4. 小结

前两天写了一篇文章介绍了一下 ElasticJob,有不少小伙伴强烈建议讲讲 xxl-job,其实 ElasticJob 本来就是一个引子,松哥本来就是想和大家分享 xxl-job 的(手动狗头。

1. xxl-job

松哥也在微信群里和小伙伴们讨论过各自到底用的是 xxl-job 还是 ElasticJob,讨论的结果就是,xxl-job 使用的人更多一些。

不说功能的优劣,我们单纯从数据上其实就能看出一些端倪:

这是 xxl-job 的 GitHub:

5a2629559483493d8213f275969247d1.png

这是 ElasticJob 的 GitHub:

2caaf3b34e96dec161090075bf636422.png

从这个数据比较上大概也能看出来 xxl-job 更火一些。注意我这里说的是更火一些,不是说 xxl-job 比 ElasticJob 更强。

xxl-job 出自大众点评,这是一个分布式轻量级的任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。

xxl-job 通过一个中心式的调度平台,调度多个执行器执行任务,调度中心通过 DB 锁保证集群分布式调度的一致性,这样扩展执行器会增大 DB 的压力,然而大部分公司的任务数,执行器并不多;xxl-job 提供了非常好用的监控页面甚至还有任务失败的邮件告警功能。不同于 ElasticJob,xxl-job 在使用时依赖 MySQL,而不需要 ZooKeeper。

ElasticJob 则出自当当,设计 ElasticJob 的初衷是为了面对高并发以及复杂的业务,即使是在业务量大,服务器多的时候也能做好任务调度,尽可能的利用服务器的资源。ElasticJob 是无中心化的,如果主服务器挂了,会自动通过 ZooKeeper 的选举机制选举出新的主服务器。因此 ElasticJob 具有良好的扩展性和可用性。

所以,你打算用哪个?

2. 运行 xxl-job

我们先把 xxl-job 跑起来,再写我们自己的代码。

首先我们先把 xxl-job 的代码搞下来,地址:

  • https://github.com/xuxueli/xxl-job

然后用 IDEA 打开项目,打开之后,有四个主要的文件夹:

8c482234efd7f0a0955b39c584de9439.png
  • doc:项目文档

  • xxl-job-admin:任务调度平台

  • xxl-job-core:核心代码

  • xxl-job-executor-samples:案例

由于 xxl-job 运行需要数据库,所以接下来我们就来配置数据库,先找到数据库脚本,在 doc/db/tables_xxl_job.sql 位置。

找到数据库脚本后,导入到数据库中执行一下,执行完成后,生成如下库和表:

fea4362fac4956cba1c54ea493edcaed.png

接下来找到 xxl-job-admin/src/main/resources/application.properties 文件,修改数据库连接信息:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

日志配置也要修改一下,在 xxl-job-admin/src/main/resources/logback.xml 文件中,有如下一行:

<property name="log.path" value="/data/applogs/xxl-job/xxl-job-admin.log"/>

如果你是 Windows 操作系统,这里肯定要改,如果你是 Mac 的话,也有可能没有这个目录的权限,因此我建议大家改一下这里的配置,改为如下这样:

<property name="log.path" value="./applogs/xxl-job/xxl-job-admin.log"/>

改为在项目运行目录下生成这个日志文件。

修改完成后,接下来我们就可以启动 xxl-job-admin 项目了,这是一个 SpringBoot 项目,找到启动类,直接运行其 main 方法即可。

项目启动成功后,浏览器输入如下地址 http://localhost:8080/xxl-job-admin/toLogin,就可以看到登录页面了:

bf4690cc2fa9fa87303310ffbeeb0da8.png

默认的登录账号是 admin/123456

看到如下页面,就是登录成功了。

591a1522298930cadf6a7ef1444c8163.png

3. 开发定时任务

3.1 项目创建及配置

接下来我们来创建一个项目,跑一个定时任务看看。

首先创建一个 SpringBoot 项目,引入 Web 依赖,如下:

6f23962545c4dab8f60ee0ed02a44967.png

项目创建成功后,引入 xxl-job 的依赖:

<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.3.0</version>
</dependency>

然后在 resources 目录下加入 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="./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>

修改 application.properties 文件,内容如下:

# web port
server.port=8089# 日志配置
logging.config=classpath:logback.xml# 配置调度中心地址
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin# 执行器和调度中心之间的通信令牌,如果没有配置,表示关闭了通信令牌的校验。
# 在 xxl-job-admin 的配置文件中,有一个一模一样的配置项,两边都配置,就会进行校验。
xxl.job.accessToken=# 配置执行器的名字
xxl.job.executor.appname=xxl-job-demo
# 执行器地址,如果没有配置,就使用 IP:PORT 作为默认值
xxl.job.executor.address=
# 执行器 ip 地址
xxl.job.executor.ip=
# 执行器端口,默认即 9999
xxl.job.executor.port=9999
# 执行器日志文件位置
xxl.job.executor.logpath=./applogs/xxl-job/jobhandler
# 执行器日志保存时间
xxl.job.executor.logretentiondays=30

各项配置的含义我已经加了注释了。

接下来再提供一个配置类,如下:

@Configuration
public class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@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() {logger.info(">>>>>>>>>>> xxl-job config init.");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;}}

其实就是把刚刚 application.properties 中的属性都配置成一个 XxlJobSpringExecutor Bean,很奇怪官方为什么没把这个搞成一个自动化配置的 Bean。

接下来我们就可以创建一个具体的定时任务了。

3.2 定时任务开发方式

对于我们 Java 工程师而言,有三种开发定时任务的方式。

3.2.1 BEAN 模式(类形式)

Bean 模式任务,支持基于类的开发方式,每个任务对应一个 Java 类。

优点:不限制项目环境,兼容性好。即使是无框架项目,如 main 方法直接启动的项目也可以提供支持。

缺点:

  • 每个任务需要占用一个Java类,造成类的浪费;

  • 不支持自动扫描任务并注入到执行器容器,需要手动注入。

开发方式:

  1. 开发一个继承自 com.xxl.job.core.handler.IJobHandler 的 JobHandler 类,实现其中任务方法。

  2. 手动通过如下方式注入到执行器容器:

XxlJobExecutor.registJobHandler("demoJobHandler", new DemoJobHandler());
  1. 在调度中心新建调度任务(后续步骤和 3.2.1 BEAN 模式(方法形式) 一致)。

这种方式用的不多,我就不给大家演示了,小伙伴们可以自行尝试。

3.2.2 BEAN模式(方法形式)

Bean 模式任务,支持基于方法的开发方式,每个任务对应一个方法,一般推荐这种方式。

优点:

  • 每个任务只需要开发一个方法,并添加 ”@XxlJob” 注解即可,更加方便、快速。

  • 支持自动扫描任务并注入到执行器容器。

缺点:

  • 要求 Spring 容器环境。

基于方法开发的任务,底层会生成 JobHandler 代理,和基于类的方式一样,任务也会以 JobHandler 的形式存在于执行器任务容器中。

开发步骤:

  1. 开发 Job 方法:

@Component
public class MyJob {@XxlJob("demoJobHandler")public ReturnT<String> demoJobHandler() throws Exception {String param = XxlJobHelper.getJobParam();XxlJobHelper.log("XXL-JOB, Hello World:{}",param);return ReturnT.SUCCESS;}
}

这里的 @XxlJob 注解标记了这是一个定时任务方法,该注解还有 init 和 destroy 属性,可以分别用来配置初始化和销毁的方法。

XxlJobHelper.getJobParam() 可以用来获取任务参数。

在这个过程中,我们需要通过 XxlJobHelper.log 打印执行日志。

默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 XxlJobHelper.handleFail/handleSuccess 自主设置任务结果。

然后启动 SpringBoot 项目。

  1. 配置调度中心,新建调度任务

接下来打开配置调度中心,找到执行器管理,点击新增,如下:

7f1eb5eb1d1b933e3d88408c4c7d309b.png

如果是自动注册的话,可以不用填机器地址。

接下来找到任务管理,并点击新增:

56a001c42f964603ead34763bc7681ed.png

基础配置都没啥好说的。

调度类型选择 CRON 表达式,CRON 表达式可以自己填,也可以点击后面的编辑按钮自动生成。

运行模式就选择 BEAN,JobHandler 的值就是我们前面 @XxlJob 注解中填的值,任务参数就是定时任务的方法参数。

配置完成后,回到执行器管理,点击查看,可以查看刚刚注册的节点信息:

235a2624c4540068d63dd359da3e8174.png

再次回到任务管理,选择启动,就可以开始定时任务的执行了:

4c8b163833241a389f5d0bc01f98c773.png

开启之后,点击调度日志,就可以看到我们系统任务执行的详细信息了:

b85aca8c6b901951ad9feecfab6c31ae.png

可以看到,每隔 5 秒执行一次。

点击调度备注,可以查看一些调度细节:

558465e97d3f716d7e8b08bd08c9e460.png

在右边操作按钮中选择执行日志:

fffdf120eee23ffc7f70ccd98ed328e4.png

可以查看执行细节:

fe1047fcc0ad6d7030ec58f4a273617e.png

红色框出来的,就是我们刚刚自己打印的。

当然这里还有一些其他玩法,小伙伴们可以自行点击按钮尝试,我就不赘述了。

3.2.3 GLUE 模式(Java)

任务以源码方式维护在调度中心,支持通过 Web IDE 在线更新,实时编译和生效,因此不需要指定 JobHandler。即在网页上写定时任务的代码,然后去执行。

这种方式个人感觉使用较少,小伙伴们了解一下即可。

开发流程如下:

  1. 调度中心->任务管理,新建调度任务,新建时选择 “GLUE模式(Java)”:

93859f4e67b54cec7902db67071bc3c2.png
  1. 开发任务代码:选中指定任务,点击该任务右侧 GLUE 按钮,将会前往 GLUE 任务的 Web IDE 界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。

b839b623fe97c4a8aaf7828fdafd30f8.png

编辑完成后,保存即可。接下来又和前面一样了,启动任务,后查看调度日志。

2ec51c7d0ab57e85aaa1bd5f7fd517f9.png

这里支持 30 个版本的版本回溯,在 GLUE 任务的 Web IDE 界面,选择右上角下拉框“版本回溯”,会列出该 GLUE 的更新历史,选择相应版本即可显示该版本代码,保存后 GLUE 代码即回退到对应的历史版本。

4. 小结

好啦,这就是我跟大家介绍的 xxl-job,感兴趣的小伙伴可以试试哦~

热门内容:
  • 新来了个技术总监:谁再用 @Async 创建线程以后就不用来了!!

  • 最新 955 不加班的公司名单(2022版)

  • 我妈今年 70 岁,受不了Windows蓝屏,用了 21 年的 Linux!YYDS!

  • 京东一面:Spring 为何需要三级缓存解决循环依赖,而不是二级缓存?我懵了。。

  • 牛啊,又一份牛逼笔记面世了

8d7b46a71dc1e49da7506564b61a730e.png

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡


http://lihuaxi.xjx100.cn/news/256086.html

相关文章

近期上海面试总结(一)

转眼来上海已经4年了&#xff0c;随着对公司业务的不断熟悉&#xff0c;同时通过与众多的人接触也渐渐加深了对职场的理解&#xff0c;从刚开始的初生牛犊不怕虎毅然来到上海&#xff0c;到如今已快有四个年头了&#xff0c;今年还是面临职场上的抉择&#xff0c;再次找工作吧&…

如何利用 C# + Python 破解猫眼电影的反爬虫机制?

在 如何利用 C# 爬取「猫眼电影&#xff1a;最受期待榜」及对应影片信息&#xff01; 这篇图文中可以看到猫眼电影对“本月新增想看人数” 和 “总想看人数”进行了字符集加密。 在 如何利用 C# 爬取「猫眼电影&#xff1a;国内票房榜」及对应影片信息&#xff01; 这篇图文中也…

开源程序员愤怒控诉!Github的「AI码农」Copilot就是寄生虫

视学算法报道 编辑&#xff1a;David【导读】以方便程序员写代码为名&#xff0c;吸血开源社区为实&#xff0c;Github的「AI码农」Copilot其实就是个寄生虫&#xff1f;Github去年推出的「AI程序员」Copilot曾一度受到程序员的热捧&#xff0c;但一个争议始终没有解决。既然是…

C# 获取图片的EXIF 信息

关于 EXIF 信息的介绍。 1 EXIF&#xff0c;是英文Exchangeable Image File(可交换图像文件)的缩写。EXIF是一种图像文件格式&#xff0c;只是文件的后缀名为jpg。EXIF信息是由数码相机在拍摄过程中采集一系列的信息&#xff0c;然后把信息放置在jpg文件的头部&#xff0c;也就…

机器学习的出现,是否意味着“古典科学”的过时?

作者&#xff1a;Laura Spinney译者&#xff1a;刘媛媛原文&#xff1a;Are we witnessing the dawn of post-theory science?让我们回忆一下&#xff0c;Isaac Newton 被一个苹果砸中头部&#xff0c;然后是怎么提出牛顿第二定律——万有引力的&#xff1f;大概过程是这样的&…

不做调参侠,重视数据及处理能力?吴恩达发起的Data-Centric赛事总结!

赛题名称&#xff1a;Data-Centric AI Competition比赛官网&#xff1a;https://https-deeplearning-ai.github.io/data-centric-comp/比赛链接&#xff1a;https://worksheets.codalab.org/worksheets/0x7a8721f11e61436e93ac8f76da83f0e6赛题介绍在大多数机器学习比赛中&…

UUID正在被NanoID取代?

欢迎关注方志朋的博客&#xff0c;回复”666“获面试宝典UUID 是软件开发中最常用的通用标识符之一。然而&#xff0c;在过去的几年里&#xff0c;其他的竞品挑战了它的存在。其中&#xff0c;NanoID 是 UUID 的主要竞争对手之一。因此&#xff0c;在本文中&#xff0c;我们将展…

ASP.NET Core 2 学习笔记(七)路由

ASP.NET Core通过路由(Routing)设定&#xff0c;将定义的URL规则找到相对应行为&#xff1b;当使用者Request的URL满足特定规则条件时&#xff0c;则自动对应到相符合的行为处理。从ASP.NET就已经存在的架构&#xff0c;而且用法也很相似&#xff0c;只有些许的不同。本篇将介绍…