SpringBoot整合Xxl-Job

一、下载Xxl-Job源代码并导入本地并运行

Github地址:
GitHub - xuxueli/xxl-job: A distributed task scheduling framework.(分布式任务调度平台XXL-JOB)

中文文档地址:
分布式任务调度平台XXL-JOB
 

1.使用Idea或Eclipse导入

2.执行sql脚本(红色标记处)

3.运行xxl-job-admin(xxl-job后台管理,主要方便管理各种各样的任务)

注意:在运行之前,需要把2的sql脚本执行完毕,并修改数据库连接池。

正常启动,访问地址为:
http://localhost:8080/xxl-job-admin

效果图,如下所示:

用户名默认为admin
密码为123456

输入后,进入这个界面,如图:

这样就表示Xxl-Job成功运行了。确保运行没问题后,就可以开始下一步。

二、添加执行器(Xxl-Job源代码就一个Example,可以复用过来,你也可以选择自己新建项目,新建项目可以在Xxl-Job基础上,也可以放在其它项目中)

1.新建一个Maven项目,命名为blog-xxl-job。

2.导入Maven依赖

<!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --><dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.2.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

3.新建application.yml配置文件并添加如下内容

#eureka
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
# web port
server.port=8081
# no web
#spring.main.web-environment=false
# 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, access token
xxl.job.accessToken=
### xxl-job executor appname
xxl.job.executor.appname=blog-xxl-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=
xxl.job.executor.port=9999
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30

可以不用eureka,这里我的项目中用到eureka所以增加该配置。

增加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>

4.编写Application类

package com.springcloud.blog.job.execute;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class BlogXxlJobExecutorApplication {public static void main(String[] args) {SpringApplication.run(BlogXxlJobExecutorApplication.class, args);}}

5.编写Job执行器

package com.springcloud.blog.job.execute.jobhandler;import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.util.ShardingUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;/*** XxlJob开发示例(Bean模式)* <p>* 开发步骤:* 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)"* 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;** @author xuxueli 2019-12-11 21:52:51*/
@Component
public class SampleXxlJob {private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);/*** 1、简单任务示例(Bean模式)*/@XxlJob("demoJobHandler")public ReturnT<String> demoJobHandler(String param) throws Exception {XxlJobLogger.log("XXL-JOB, Hello World.");for (int i = 0; i < 5; i++) {XxlJobLogger.log("beat at:" + i);TimeUnit.SECONDS.sleep(2);}return ReturnT.SUCCESS;}/*** 2、分片广播任务*/@XxlJob("shardingJobHandler")public ReturnT<String> shardingJobHandler(String param) throws Exception {// 分片参数ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());// 业务逻辑for (int i = 0; i < shardingVO.getTotal(); i++) {if (i == shardingVO.getIndex()) {XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);} else {XxlJobLogger.log("第 {} 片, 忽略", i);}}return ReturnT.SUCCESS;}/*** 3、命令行任务*/@XxlJob("commandJobHandler")public ReturnT<String> commandJobHandler(String param) throws Exception {String command = param;int exitValue = -1;BufferedReader bufferedReader = null;try {// command processProcess process = Runtime.getRuntime().exec(command);BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));// command logString line;while ((line = bufferedReader.readLine()) != null) {XxlJobLogger.log(line);}// command exitprocess.waitFor();exitValue = process.exitValue();} catch (Exception e) {XxlJobLogger.log(e);} finally {if (bufferedReader != null) {bufferedReader.close();}}if (exitValue == 0) {return IJobHandler.SUCCESS;} else {return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value(" + exitValue + ") is failed");}}/*** 4、跨平台Http任务* 参数示例:* "url: http://www.baidu.com\n" +* "method: get\n" +* "data: content\n";*/@XxlJob("httpJobHandler")public ReturnT<String> httpJobHandler(String param) throws Exception {// param parseif (param == null || param.trim().length() == 0) {XxlJobLogger.log("param[" + param + "] invalid.");return ReturnT.FAIL;}String[] httpParams = param.split("\n");String url = null;String method = null;String data = null;for (String httpParam : httpParams) {if (httpParam.startsWith("url:")) {url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();}if (httpParam.startsWith("method:")) {method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();}if (httpParam.startsWith("data:")) {data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();}}// param validif (url == null || url.trim().length() == 0) {XxlJobLogger.log("url[" + url + "] invalid.");return ReturnT.FAIL;}if (method == null || !Arrays.asList("GET", "POST").contains(method)) {XxlJobLogger.log("method[" + method + "] invalid.");return ReturnT.FAIL;}// requestHttpURLConnection connection = null;BufferedReader bufferedReader = null;try {// connectionURL realUrl = new URL(url);connection = (HttpURLConnection) realUrl.openConnection();// connection settingconnection.setRequestMethod(method);connection.setDoOutput(true);connection.setDoInput(true);connection.setUseCaches(false);connection.setReadTimeout(5 * 1000);connection.setConnectTimeout(3 * 1000);connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");// do connectionconnection.connect();// dataif (data != null && data.trim().length() > 0) {DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());dataOutputStream.write(data.getBytes("UTF-8"));dataOutputStream.flush();dataOutputStream.close();}// valid StatusCodeint statusCode = connection.getResponseCode();if (statusCode != 200) {throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");}// resultbufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));StringBuilder result = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {result.append(line);}String responseMsg = result.toString();XxlJobLogger.log(responseMsg);return ReturnT.SUCCESS;} catch (Exception e) {XxlJobLogger.log(e);return ReturnT.FAIL;} finally {try {if (bufferedReader != null) {bufferedReader.close();}if (connection != null) {connection.disconnect();}} catch (Exception e2) {XxlJobLogger.log(e2);}}}/*** 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;*/@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")public ReturnT<String> demoJobHandler2(String param) throws Exception {XxlJobLogger.log("XXL-JOB, Hello World.");return ReturnT.SUCCESS;}public void init() {logger.info("init");}public void destroy() {logger.info("destory");}}

6.增加XxlJobConfig配置类

package com.springcloud.blog.job.execute.core.config;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;@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;}}

三、结合Xxl-Job后台系统增加定时任务

1.配置执行器

执行器地址为(与blog-xxl-job中application.yml配置文件里的执行器地址需要保持一致,否则会注册失败,导致任务执行不了:

2.添加任务

3.任务执行成功的标志

四、为什么选择Xxl-Job

当初选择使用Xxl-Job有这么几个原因:
第一、团队里有好几个人上一家公司或上上家公司用过。
第二、这个生态比较丰富且开源。
第三、确实非常容易上手且轻量化(轻量化的一个体现就是非侵入式)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/759235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习_神经网络

文章目录 简介反向传播小结 简介 为了构建神经网络模型&#xff0c;我们需要首先思考大脑中的神经网络是怎样的&#xff1f;每一个神经元都可以被认为是一个处理单元/神经核&#xff0c;它含有许多输入/树突&#xff0c;并且有一个输出/轴突。神经网络是大量神经元相互链接并通…

【笔试】互联网校招技术研发岗 非技术岗笔试准备方向

【笔试】互联网校招技术研发岗笔试准备方向 文章目录 1、研发&#xff1a;软件开发&#xff08;选择&#xff09;2、研发&#xff1a;非技术题&#xff08;选择&#xff09;3、研发&#xff1a;编程题4、产品、运营、项目、视觉、设计、交互5、人力、财务、行政、咨询、管理6、…

计算机网络简答题:复试+期末

文章目录 1.计算机网络的功能:2.计算机网络的分类:3.主机间的通信方式:4.电报交换、报文交换、分组交换的区别:5.计算机网络的性能指标:6.0SI模型和TCP/IP模型:7.通信信通的方式:8.端到端的通信与点到点通信的区别:9.同步通信和异步通信:10.频分复用、时分复用、波分复用和码分…

H5 与 App、网页之间的通信

前言 本文整理工作中 H5 嵌入 Android、iOS 与 PC 网页后&#xff0c;如何与各端通信。&#xff08;提供 H5 端的代码&#xff09; 环境判断 const ua navigator.userAgent.toLowerCase()const isAndroid /android/i.test(ua)const isIos /iphone|ipod|ios/i.test(ua)cons…

笔试题——得物春招实习

开幕式排练 题目描述 导演在组织进行大运会开幕式的排练&#xff0c;其中一个环节是需要参演人员围成一个环形。演出人员站成了一圈&#xff0c;出于美观度的考虑&#xff0c;导演不希望某一个演员身边的其他人比他低太多或者高太多。 现在给出n个参演人员的身高&#xff0c;问…

使用Pygame做一个乒乓球游戏(2)使用精灵重构

本节没有添加新的功能&#xff0c;而是将前面的功能使用精灵类(pygame.sprite.Sprite) 重构。 顺便我们使用图片美化了一下程序。 看到之前的代码&#xff0c;你会发现代码有点混乱&#xff0c;很多地方使用了全局变量(global)。 本节我们将使用类进行重构。 Block(Sprite)…

NCV7428D15R2G中文资料PDF数据手册参数引脚图图片价格概述参数芯片特性原理

产品概述&#xff1a; NCV7428 是一款系统基础芯片 (SBC)&#xff0c;集成了汽车电子控制单元 (ECU) 中常见的功能。NCV7428 为应用微控制器和其他负载提供低电压电源并对其进行监控&#xff0c;包括了一个 LIN 收发器。 产品特性&#xff1a; 控制逻辑3.3 V或5 V VOUT电源&…

每天一个数据分析题(二百二十)

在集成学习的GBDT算法中&#xff0c;每次训练新的决策树的目的是( )&#xff1f; A. 预测原始数据的标签 B. 预测上一个模型的残差 C. 降低模型的偏差 D. 降低模型的方差 题目来源于CDA模拟题库 点击此处获取答案

python练习3

用户登录注册案例 while True: print("\t\t\t英雄商城登录界面\n") print("~*"*38) print("\t\t\t1.用户登录\n") print("\t\t\t2.用户注册\n") print("\t\t\t3.退出系统\n") print("~*"*38) choice input("…

Spark-Scala语言实战(4)

在之前的文章中&#xff0c;我们学习了如何在scala中定义无参&#xff0c;带参以及匿名函数。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言…

四、HarmonyOS应用开发-ArkTS开发语言介绍

目录 1、TypeScript快速入门 1.1、编程语言介绍 1.2、基础类型 1.3、条件语句 1.4、函数 1.5、类 1.6、模块 1.7、迭代器 2、ArkTs 基础&#xff08;浅析ArkTS的起源和演进&#xff09; 2.1、引言 2.2、JS 2.3、TS 2.4、ArkTS 2.5、下一步演进 3、ArkTs 开发实践…

Verilog基础:always结构和initial结构

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 always和initial是Verilog中的核心&#xff0c;它们被称为结构(construct)&#xff0c;用于组织语句的执行方式。下面将分别对这两者进行阐述。 always结构 图1是…

弹框el-dialog title展示不下,鼠标hover显示tip

el-dialog title展示不下&#xff0c;鼠标hover显示tip <el-dialog:visible.sync"shows":close-on-click-modal"false"v-dialogDragwidth"520px"><template #title><div class"custom-title"><el-tooltipplaceme…

【文件操作和IO】

文件操作和IO 1.文件2. 硬盘上文件的目录结构3. 文件路径4. 文件重要分类&#xff1a;5. Java中操作文件5.1 Java对于文件操作的API5.2 Java中使用File类来进行文件操作5.3 File类属性5.4 构造方法5.5 方法&#xff1a; 6. 文件内容的读写 -- 文件流&#xff08;数据流&#xf…

Apache Superset

前言 最近在准备一个小的项目&#xff0c;需要对 Hive 的数据进行展示&#xff0c;所以想到了把 Hive 的数据导出到 MySQL 然后用 Superset 进行展示。 Superset 1.1 Superset概述 Apache Superset是一个现代的数据探索和可视化平台。它功能强大且十分易用&#xff0c;可对接…

kubesphere all in one部署Jenkins提示1 Insufficient cpu

原因 devops 至少一个cpu&#xff08;1000m&#xff09;&#xff0c;但是其他资源已经占用了很多cpu CPU 资源以 CPU 单位度量。Kubernetes 中的一个 CPU 等同于&#xff1a; 1 个 AWS vCPU 1 个 GCP核心 1 个 Azure vCore 裸机上具有超线程能力的英特尔处理器上的 1 个超线程…

Qt_Note10_QML_ComponentLoader

在 QML 中&#xff0c;Component 和 Loader 是两个重要的元素&#xff0c;用于动态创建和加载其他 QML 组件。 Component&#xff08;组件&#xff09;&#xff1a; Component 是一个可重复使用的 QML 定义&#xff0c;类似于一个模板或类的概念。它可以定义一个独立的 QML组件…

spaCy NLP库的模型的下载、安装和使用说明书

文章目录 1 前言2 安装3 模型命名规范3.1 模型版本控制3.2 支持对旧版本的兼容 4 下载模型5 加载和使用模型6 手动下载和安装7 spaCy v1.x模型的命名规范8 问题和错误报告 1 前言 explosion网址&#xff1a;https://explosion.ai/ spaCy下载网址&#xff1a;https://explosion…

RISC-V架构的三种特权模式如何切换

1、RISC-V的三种特权模式 特权模式功能描述机器模式&#xff08;M-mode&#xff09;具有最高特权等级&#xff0c;具有访问所有资源的权限&#xff0c;通常运行固件和内核用户模式&#xff08;U-mode&#xff09;权限要比M模式低&#xff0c;通常是用来运行操作系统内核管理员…

MyBatis3源码深度解析(十七)MyBatis缓存(一)一级缓存和二级缓存的实现原理

文章目录 前言第六章 MyBatis缓存6.1 MyBatis缓存实现类6.2 MyBatis一级缓存实现原理6.2.1 一级缓存在查询时的使用6.2.2 一级缓存在更新时的清空 6.3 MyBatis二级缓存的实现原理6.3.1 实现的二级缓存的Executor类型6.3.2 二级缓存在查询时使用6.3.3 二级缓存在更新时清空 前言…