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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
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)







相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
6月前
|
弹性计算 机器人 应用服务中间件
一键部署开源Qwen3并集成到钉钉、企业微信
Qwen3系列模型现已正式发布并开源,包含8款“混合推理模型”,其中涵盖两款MoE模型(Qwen3-235B-A22B与Qwen3-30B-A3B)及六个Dense模型。阿里云计算巢已支持Qwen3-235B-A22B和Qwen3-32B的私有化部署,用户可通过计算巢轻松完成部署,并借助AppFlow集成至钉钉机器人或企业微信。文档详细介绍了从模型部署、创建应用到配置机器人的全流程,帮助用户快速实现智能助手的接入与使用。
432 19
一键部署开源Qwen3并集成到钉钉、企业微信
|
4月前
|
存储 文字识别 自然语言处理
通义大模型在文档自动化处理中的高效部署指南(OCR集成与批量处理优化)
本文深入探讨了通义大模型在文档自动化处理中的应用,重点解决传统OCR识别精度低、效率瓶颈等问题。通过多模态编码与跨模态融合技术,通义大模型实现了高精度的文本检测与版面分析。文章详细介绍了OCR集成流程、批量处理优化策略及实战案例,展示了动态批处理和分布式架构带来的性能提升。实验结果表明,优化后系统处理速度可达210页/分钟,准确率达96.8%,单文档延迟降至0.3秒,为文档处理领域提供了高效解决方案。
436 0
|
5月前
|
JSON 缓存 并行计算
NVIDIA 实现通义千问 Qwen3 的生产级应用集成和部署
阿里巴巴近期开源了通义千问Qwen3大语言模型(LLM),包含两款混合专家模型(MoE)235B-A22B与30B-A3B,以及六款稠密模型(Dense)从0.6B到32B不等。开发者可基于NVIDIA GPU使用TensorRT-LLM、Ollama、SGLang、vLLM等框架高效部署Qwen3系列模型,实现快速词元生成和生产级应用开发。
|
6月前
|
安全 Java 持续交付
如何实现上传jar直接部署成功,这篇文章直接带你上手springboot实现jar包热更新!
本文详细讲解了在Spring Boot应用中实现Jar包热更新的实践方法。通过自定义类加载器(`HotClassLoader`),动态加载和卸载指定目录下的Jar包,结合Spring Bean动态注册机制,使新加载的类能够被Spring容器管理。同时,提供了文件上传接口,方便用户手动触发Jar包更新。文章还强调了安全性、依赖管理和线程安全等注意事项,并给出了测试步骤和总结,帮助开发者高效实现热更新功能,减少服务中断和提升开发效率。
|
8月前
|
人工智能 Kubernetes jenkins
容器化AI模型的持续集成与持续交付(CI/CD):自动化模型更新与部署
在前几篇文章中,我们探讨了容器化AI模型的部署、监控、弹性伸缩及安全防护。为加速模型迭代以适应新数据和业务需求,需实现容器化AI模型的持续集成与持续交付(CI/CD)。CI/CD通过自动化构建、测试和部署流程,提高模型更新速度和质量,降低部署风险,增强团队协作。使用Jenkins和Kubernetes可构建高效CI/CD流水线,自动化模型开发和部署,确保环境一致性并提升整体效率。
|
3月前
|
物联网 Linux 开发者
快速部署自己私有MQTT-Broker-下载安装到运行不到一分钟,快速简单且易于集成到自己项目中
本文给物联网开发的朋友推荐的是GMQT,让物联网开发者快速拥有合适自己的MQTT-Broker,本文从下载程序到安装部署手把手教大家安装用上私有化MQTT服务器。
899 5
|
3月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
358 13
|
6月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
401 70
|
5月前
|
人工智能 安全 Shell
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
Jupyter MCP服务器基于模型上下文协议(MCP),实现大型语言模型与Jupyter环境的无缝集成。它通过标准化接口,让AI模型安全访问和操作Jupyter核心组件,如内核、文件系统和终端。本文深入解析其技术架构、功能特性及部署方法。MCP服务器解决了传统AI模型缺乏实时上下文感知的问题,支持代码执行、变量状态获取、文件管理等功能,提升编程效率。同时,严格的权限控制确保了安全性。作为智能化交互工具,Jupyter MCP为动态计算环境与AI模型之间搭建了高效桥梁。
337 2
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
|
3月前
|
Prometheus 监控 Cloud Native
Docker 部署 Prometheus 和 Grafana 监控 Spring Boot 服务
Docker 部署 Prometheus 和 Grafana 监控 Spring Boot 服务实现步骤