xxl-job的部署及springboot集成使用

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: XXL-Job是一个分布式任务调度平台,可进行任务调度、管理和监控,并提供任务分片、失败重试、动态分配等功能。它是一个开源项目,基于Spring Boot和Quartz开发,支持常见的任务调度场景。XXL-Job的使用相对简单,只需要简单配置即可实现任务调度。同时,它提供了丰富的管理和监控功能,可以方便地查看任务执行状态、日志等。在企业中,XXL-Job广泛应用于一些大型、分布式的系统中,如电商系统、金融系统等。它的高性能、高可靠性、易使用性等特点深受用户的喜爱。

# 介绍

XXL-Job是一个分布式任务调度平台,可进行任务调度、管理和监控,并提供任务分片、失败重试、动态分配等功能。它是一个开源项目,基于Spring Boot和Quartz开发,支持常见的任务调度场景。


XXL-Job的使用相对简单,只需要简单配置即可实现任务调度。同时,它提供了丰富的管理和监控功能,可以方便地查看任务执行状态、日志等。


在企业中,XXL-Job广泛应用于一些大型、分布式的系统中,如电商系统、金融系统等。它的高性能、高可靠性、易使用性等特点深受用户的喜爱。


# 1.安装mysql

```

docker run -d \

--name mysql \

-p 3306:3306 \

-e MYSQL_ROOT_PASSWORD=root1234567 \

mysql:8.0

```

# 2.初始化下载的数据

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

https://github.com/xuxueli/xxl-job/archive/refs/tags/2.4.0.tar.gz

解压后执行xxl-job-2.4.0.tar\xxl-job-2.4.0\doc\db\tables_xxl_job.sql


# 3.启动xxl-job-admin

默认登录 admin/123456

```

docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://172.24.31.53:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai

--spring.datasource.username=root --spring.datasource.password=root1234567" -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin  -d  xuxueli/xxl-job-admin:2.4.0

```


http://172.24.31.53:8080/xxl-job-admin/


![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/a1584966b2bf42afb35f5ece6691604d.png)




# 3.springboot集成

## 3.1依赖

```

<dependency>

  <groupId>com.xuxueli</groupId>

  <artifactId>xxl-job-core</artifactId>

  <version>2.4.0</version>

 </dependency>

```

## 3.2配置

```

xxl:

 job:

   admin:

     addresses: http://101.200.153.111:8080/xxl-job-admin

   accessToken: default_token

   executor:

     appname: xxl-job-executor-sample

     address:

     ip: 101.200.153.111

     port: 4567

     logpath: /data/applogs/xxl-job/jobhandler

     logretentiondays: 30

```



## 3.3代码

```

package com.lys.lys_admin_api.xxl;


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 https://liuyunshengsir.blog.csdn.net/

*/

@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;



   @Bean

   public 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;

   }


   /**

    * 针对多网卡、容器内部署等情况,可借助 "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();

    */



}

```

jobhandler 样例

```

package com.lys.lys_admin_api.xxl.jobhandler;


import com.xxl.job.core.context.XxlJobHelper;

import com.xxl.job.core.handler.annotation.XxlJob;

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模式)

*

* 开发步骤:

*      1、任务开发:在Spring Bean实例中,开发Job方法;

*      2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。

*      3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;

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

*

* @author https://liuyunshengsir.blog.csdn.net/

*/

@Component

public class SampleXxlJob {

   private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);



   /**

    * 1、简单任务示例(Bean模式)

    */

   @XxlJob("demoJobHandlerLYS")

   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);

       }

       // default success

   }



   /**

    * 2、分片广播任务

    */

   @XxlJob("shardingJobHandler")

   public void shardingJobHandler() throws Exception {


       // 分片参数

       int shardIndex = XxlJobHelper.getShardIndex();

       int shardTotal = XxlJobHelper.getShardTotal();


       XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);


       // 业务逻辑

       for (int i = 0; i < shardTotal; i++) {

           if (i == shardIndex) {

               XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);

           } else {

               XxlJobHelper.log("第 {} 片, 忽略", i);

           }

       }


   }



   /**

    * 3、命令行任务

    */

   @XxlJob("commandJobHandler")

   public void commandJobHandler() throws Exception {

       String command = XxlJobHelper.getJobParam();

       int exitValue = -1;


       BufferedReader bufferedReader = null;

       try {

           // command process

           ProcessBuilder processBuilder = new ProcessBuilder();

           processBuilder.command(command);

           processBuilder.redirectErrorStream(true);


           Process process = processBuilder.start();

           //Process process = Runtime.getRuntime().exec(command);


           BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());

           bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));


           // command log

           String line;

           while ((line = bufferedReader.readLine()) != null) {

               XxlJobHelper.log(line);

           }


           // command exit

           process.waitFor();

           exitValue = process.exitValue();

       } catch (Exception e) {

           XxlJobHelper.log(e);

       } finally {

           if (bufferedReader != null) {

               bufferedReader.close();

           }

       }


       if (exitValue == 0) {

           // default success

       } else {

           XxlJobHelper.handleFail("command exit value("+exitValue+") is failed");

       }


   }



   /**

    * 4、跨平台Http任务

    *  参数示例:

    *      "url: http://www.baidu.com\n" +

    *      "method: get\n" +

    *      "data: content\n";

    */

   @XxlJob("httpJobHandler")

   public void httpJobHandler() throws Exception {


       // param parse

       String param = XxlJobHelper.getJobParam();

       if (param==null || param.trim().length()==0) {

           XxlJobHelper.log("param["+ param +"] invalid.");


           XxlJobHelper.handleFail();

           return;

       }


       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 valid

       if (url==null || url.trim().length()==0) {

           XxlJobHelper.log("url["+ url +"] invalid.");


           XxlJobHelper.handleFail();

           return;

       }

       if (method==null || !Arrays.asList("GET", "POST").contains(method)) {

           XxlJobHelper.log("method["+ method +"] invalid.");


           XxlJobHelper.handleFail();

           return;

       }

       boolean isPostMethod = method.equals("POST");


       // request

       HttpURLConnection connection = null;

       BufferedReader bufferedReader = null;

       try {

           // connection

           URL realUrl = new URL(url);

           connection = (HttpURLConnection) realUrl.openConnection();


           // connection setting

           connection.setRequestMethod(method);

           connection.setDoOutput(isPostMethod);

           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 connection

           connection.connect();


           // data

           if (isPostMethod && data!=null && data.trim().length()>0) {

               DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());

               dataOutputStream.write(data.getBytes("UTF-8"));

               dataOutputStream.flush();

               dataOutputStream.close();

           }


           // valid StatusCode

           int statusCode = connection.getResponseCode();

           if (statusCode != 200) {

               throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");

           }


           // result

           bufferedReader = 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();


           XxlJobHelper.log(responseMsg);


           return;

       } catch (Exception e) {

           XxlJobHelper.log(e);


           XxlJobHelper.handleFail();

           return;

       } finally {

           try {

               if (bufferedReader != null) {

                   bufferedReader.close();

               }

               if (connection != null) {

                   connection.disconnect();

               }

           } catch (Exception e2) {

               XxlJobHelper.log(e2);

           }

       }


   }


   /**

    * 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;

    */

   @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")

   public void demoJobHandler2() throws Exception {

       XxlJobHelper.log("XXL-JOB, Hello World.");

   }

   public void init(){

       logger.info("init");

   }

   public void destroy(){

       logger.info("destroy");

   }



}


```

## 3.4 页面查看

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/f3c93ab10d774e3cb0ef71555decf4df.png)







相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
Java Maven Docker
gitlab-ci 集成 k3s 部署spring boot 应用
gitlab-ci 集成 k3s 部署spring boot 应用
|
1月前
|
运维 监控 Devops
DevOps实践:持续集成与部署的自动化之旅
【10月更文挑战第7天】在软件开发领域,DevOps已成为提升效率、加速交付和确保质量的关键策略。本文将深入探讨如何通过实施持续集成(CI)和持续部署(CD)来自动化开发流程,从而优化运维工作。我们将从基础概念入手,逐步过渡到实际操作,包括工具选择、流程设计以及监控和反馈机制的建立。最终,我们不仅会展示如何实现这一自动化流程,还会讨论如何克服常见的挑战,以确保成功实施。
64 9
|
1月前
|
数据可视化 Java 应用服务中间件
springboot打war包,成功部署
这篇文章介绍了如何将Spring Boot项目打包成WAR文件,并成功部署到Tomcat服务器的详细步骤。
116 0
springboot打war包,成功部署
|
1月前
|
监控 Devops 测试技术
DevOps实践:持续集成与部署的自动化之路
【9月更文挑战第30天】在软件工程的世界中,DevOps已成为提升开发效率、确保软件质量和加快交付速度的关键策略。本文将深入探讨如何通过自动化工具和流程实现持续集成(CI)与持续部署(CD),从而优化软件开发周期。我们将从基础概念出发,逐步深入到实际操作,最终展示如何构建一个高效的自动化流水线,以支持快速迭代和高质量发布。
57 7
|
2月前
|
Devops jenkins Java
DevOps实践:持续集成和部署的自动化之旅
【9月更文挑战第20天】在软件开发的世界里,速度和质量是至关重要的。本文将带领读者踏上一场自动化之旅,深入探索DevOps文化中的两大支柱——持续集成(CI)和持续部署(CD)。我们将通过一个实际的案例,展示如何利用现代工具和技术实现代码从编写到部署的无缝转换,确保软件交付的高效性和可靠性。准备好让你的开发流程变得更加流畅和高效了吗?让我们开始吧!
|
29天前
|
安全 Java 测试技术
ToB项目身份认证AD集成(二):快速搞定window server 2003部署AD域服务并支持ssl
本文详细介绍了如何搭建本地AD域控测试环境,包括安装AD域服务、测试LDAP接口及配置LDAPS的过程。通过运行自签名证书生成脚本和手动部署证书,实现安全的SSL连接,适用于ToB项目的身份认证集成。文中还提供了相关系列文章链接,便于读者深入了解AD和LDAP的基础知识。
|
2月前
|
缓存 数据可视化 jenkins
推荐2款实用的持续集成与部署(CI&CD)自动化工具
推荐2款实用的持续集成与部署(CI&CD)自动化工具
177 1
|
2月前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
74 2
|
3月前
|
开发者 算法 虚拟化
惊爆!Uno Platform 调试与性能分析终极攻略,从工具运用到代码优化,带你攻克开发难题成就完美应用
【8月更文挑战第31天】在 Uno Platform 中,调试可通过 Visual Studio 设置断点和逐步执行代码实现,同时浏览器开发者工具有助于 Web 版本调试。性能分析则利用 Visual Studio 的性能分析器检查 CPU 和内存使用情况,还可通过记录时间戳进行简单分析。优化性能涉及代码逻辑优化、资源管理和用户界面简化,综合利用平台提供的工具和技术,确保应用高效稳定运行。
83 0
|
4月前
|
监控 druid Java
spring boot 集成配置阿里 Druid监控配置
spring boot 集成配置阿里 Druid监控配置
290 6