首页 > 其他分享 >xxl-job,任务调度中心快速上手

xxl-job,任务调度中心快速上手

时间:2024-12-07 18:53:46浏览次数:3  
标签:执行器 executor job org import 任务调度 xxl

前言

XXL-JOB是一个可以在WEB界面配置执行定时任务中间件,支持分布式服务调用,XXL-JOB自身也可以部署多个节点组成集群,本身是一个基于SpringBoot的Java WEB程序,我们可以通过下载GitHub源码进行部署。

一、XXL-JOB 安装教程

进入 xxl-job官网,里面有更详细的教程 XXL-JOB官网

1、下载源码
git clone http://gitee.com/xuxueli0323/xxl-job

通过IDEA打开后目录如下:

2、初始化"调度数据库"

“调度数据库初始化SQL脚本” 位置为:

`/xxl-job/doc/db/tables_xxl_job.sql`

没错,你得执行这个sql文件到你的数据库中,执行完后 会有如下库和表出现在数据库中

3、项目构造
  1. xxl-job-admin:调度中心
  2. xxl-job-core:公共依赖
  3. xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
    1. :xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,本文章以这种方式介绍,官方推荐该方式;
    2. :xxl-job-executor-sample-frameless:无框架版本;
好了~,到这一步你的XXL—JOB算是装好了,下一步让我们来启动它

二、启动调度中心前的准备

  1. 调度中心项目:xxl-job-admin 《超关键,起的就是这玩意儿》
  2. 作用:统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。

先修改一下调度中心xxl-job-admin的配置文件。

`/xxl-job/xxl-job-admin/src/main/resources/application.properties`

主要修改数据库为自己的刚才执行sql的库

### xxl-job, datasource
spring.datasource.url=jdbc:mysql://123.45.678.90:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=xxx用户
spring.datasource.password=xxx密码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

然后启动项目

`xxl-job-admin/src/main/java/com/xxl/job/admin/XxlJobAdminApplication.java`

调度中心访问地址:http://localhost:8080/xxl-job-admin (该地址执行器将会使用到,作为回调地址)

默认登录账号 “admin/123456”, 登录后运行界面如下图所示。

三、启动执行器项目

1、maven依赖

确认执行器项目的pom文件中引入了 xxl-job-core 的maven依赖;

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>${project.parent.version}</version> <!-- 跟随调度中心的版本 -->
</dependency>
2、执行器配置

执行器配置,配置文件地址:

/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties

执行器配置,配置内容说明:

# 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=default_token

### xxl-job executor appname 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
### 执行器分组名称,关系到会注册到哪个组里
xxl.job.executor.appname=learn-xxl-job
### 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

主要就是xxl.job.admin.addressesxxl.job.executor.appname 这俩,第一个必须指向正确的调度中心地址

3、创建启动配置文件

因xxl-job没有使用spring-boot-starter,需自行将配置类注入到spring容器中。

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.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();
     */

}

然后启动执行器,成功注册后,在调度中心可以看到

四、编写一个定时任务

1、创建一个任务调度

注意@XxlJob(“sendSMS”)注解中的sendSMS,即任务的唯一名称,之后执行任务调度将会使用。

// 显示在调度中心日志的内容
XxlJobHelper.log("无参数执行一个定时/指定任务");
// 获取任务参数
XxlJobHelper.getJobParam();
// 用于在任务执行失败时向调度中心报告失败信息。调度中心会记录任务的失败状态,并可以根据配置进行相应的处理(如重试、告警等)。
XxlJobHelper.handleFail("参数传递异常");
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;

/**
 * @author Cyf
 * @ Date: 2024/12/6 下午5:23
 */
@Component
public class MyJob {
    public static final Logger log = LoggerFactory.getLogger(MyJob.class);
    
//	  可使用@Resource/@Autowire注入执行器里中的其他服务
//    @Autowired
//    private UserService userService;

    /**
     * 无需参数传递
     * @throws Exception
     */
    @XxlJob("sendSMS")
    public void sendSMS() throws Exception {
        
        // 记录任务开始的日志
        //只会显示再项目日志中
        log.info("slf4j的框架");
        //只会显示在xxl-job的日志中
        XxlJobHelper.log("无参数执行一个定时/指定任务");
        
    }

    /**
     * 单个参数传递
     * @throws Exception
     */
    @XxlJob("oneParameter")
    public void sendMessage() throws Exception {
        XxlJobHelper.log("单个任务参数为:" + XxlJobHelper.getJobParam());
    }

    /**
     * 多个参数,应用 , 分割
     * @throws Exception
     */
    @XxlJob("moreParameters")
    public void sendMessage2() throws Exception {
        try {
            // 获取参数
            String param = XxlJobHelper.getJobParam();
            String[] methodParams = param.split(",");

            XxlJobHelper.log("参数1为:" + methodParams[0] + ",参数2为" + methodParams[1]);
        }catch (Exception e){
            XxlJobHelper.handleFail("参数传递异常");
        }
    }
}

2、 xxl-job-admin中添加任务

在Cron中配置任务调度的时间周期,可选择CRON或固定速度。JobHandler中需配置@XxlJob注解中的名称。

3、执行任务

4、查看执行日志


项目日志

18:23:05.259 logback [xxl-job, JobThread-9-1733566985234] INFO  c.x.j.e.service.jobhandler.MyJob - slf4j的框架
4、定制化拦截器

可以通过Spring Aop拦截@XxlJob注解,去处理一些通用业务逻辑。
例如追加TraceId 进行日志定位

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * @author 为每个执行器增加traceId
 */
@Slf4j
@Order(1)
@Aspect
@Component
public class XxlJobAspect {

    @Pointcut("@annotation(com.xxl.job.core.handler.annotation.XxlJob)")
    public void pointCut() {
    }

    @Around("pointCut() && @annotation(xxlJob)")
    public Object doAround(ProceedingJoinPoint point, XxlJob xxlJob) {
        String traceId = UUID.randomUUID().toString();
        MDC.put("traceId", traceId);

        String jobName = xxlJob.value();
        StopWatch sw = new StopWatch();
        sw.start();
        log.info("定时任务[{}]开始,开始时间:{},输入参数:{}", jobName, LocalDateTime.now(), XxlJobHelper.getJobParam());
        Object proceed;
        try {
            proceed = point.proceed();
        } catch (Throwable e) {
            log.warn("定时任务[{}]执行失败", jobName, e);
            failure(e, traceId);
            return null;
        }
        sw.stop();
        log.info("定时任务[{}]结束!执行时间:{} ms", jobName, sw.getTotalTimeMillis());
        success(traceId);
        return proceed;
    }

    private void failure(Throwable e, String traceId) {
        //将异常信息输出到xxl-job日志中
        XxlJobHelper.handleFail("traceId=" + traceId + ",<br>exception=" + getStackTrace(e));
        MDC.remove("traceId");
    }

    private void success(String traceId) {
        XxlJobHelper.handleSuccess("traceId=" + traceId);
        MDC.remove("traceId");
    }

    /**
     * 该方法来捕获异常的堆栈跟踪信息,并将其转换为字符串
     * @param e 异常信息
     * @return 堆栈跟踪字符串
     */
    private String getStackTrace(Throwable e) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        e.printStackTrace(printWriter);
        return stringWriter.toString();
    }

}

在日志中添加TraceId,快速定位任务链路

<?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"/>
<!--    定义输出格式 -->
    <!-- %X{traceId} 添加traceId到日志中 -->
    <property name="PATTERN" value="%d{HH:mm:ss.SSS} %contextName [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n" />
<!--   ConsoleAppender:表示日志将输出到控制台。 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
<!--            引入格式 -->
            <pattern>${PATTERN}</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="file"/>
        <!--   引用了前面定义的 STDOUT appender,表示所有符合 info 级别及以上的日志消息都将通过 STDOUT 输出到控制台。-->
        <appender-ref ref="STDOUT"/>
    </root>

</configuration>

然后重启项目,再次执行任务将打印如下日志

18:23:05.254 logback [xxl-job, JobThread-9-1733566985234] [531a6504-13bc-4bc6-91de-ff64b235110d] INFO  c.x.j.e.core.config.XxlJobAspect - 定时任务[sendSMS]开始,开始时间:2024-12-07T18:23:05.254,输入参数:
18:23:05.259 logback [xxl-job, JobThread-9-1733566985234] [531a6504-13bc-4bc6-91de-ff64b235110d] INFO  c.x.j.e.service.jobhandler.MyJob - slf4j的框架
18:23:05.260 logback [xxl-job, JobThread-9-1733566985234] [531a6504-13bc-4bc6-91de-ff64b235110d] INFO  c.x.j.e.core.config.XxlJobAspect - 定时任务[sendSMS]结束!执行时间:10 ms

[531a6504-13bc-4bc6-91de-ff64b235110d] 为该次请求中的traceId,在调度日志中也会有:

结束语

个人感觉这是个很强大的一款任务调度中心,从0到1帮助小白快速上手,如果此文章对你有帮助,希望留个赞再走 v

标签:执行器,executor,job,org,import,任务调度,xxl
From: https://www.cnblogs.com/promiseforyou/p/18592471

相关文章

  • Abaqus常见问题之LOAD、JOB、Visualization
    本次内容参考曹金凤、石亦平老师所著的《ABAQUS有限元分析常见问题解答》LOAD模块:1) 利用幅值曲线可以描述随时间变化的载荷与边界条件,常见的幅值曲线类型包括:默认的线性过渡(Ramp)幅值曲线、表格型幅值曲线、等间距幅值曲线、以及周期型幅值曲线。2) 实体单元只具有......
  • AI绘画 Stable Diffusion 【真人模型】:一款适合画中国女孩的国产真人大模型MexxL_LCM2
    目前StableDiffusion大模型中,真人模型可谓,百发齐放,精彩纷呈,令人目眩神迷。真人模型充分展现着栩栩如生的美态与神采。逼真的面部表情、流畅自然的动作,融合了真实和[虚拟的]完美之美。然而很多真人大模型都是参照着西方女性的特征,在绘制中国女性方面,还略微逊色。今天就和大......
  • k8s阶段05 Operator, DaemonSet, Job, CronJob, Ingress和Ingress Controller(蓝绿/恢
    StatefulSet:编排有状态应用基本要求:需要给每个实例惟一且固定的标识,依赖于一个专用的HeadlessService;需要给每个实例一个专用的PVC卷,该卷要来自volumeTemplateClaim,卷的标识“template_name-pod_name”;PodManagementPolicy:OrderedReady:按顺序,依次......
  • In Cursor IDE, which one is better to process the above job, composer normal mo
    Forprocessingalarge-scaledocumentationorganizationtask,AgentmodeisbetterthanComposermodeinCursorIDE.Here'swhy:AgentModeAdvantages:ToolIntegrationDirectaccesstoall8agenttools:-list_dir-codebase_search-read_file......
  • 解决测试环境下 xxl-job 执行失败的问题
    问题xxljob在测试环境经常执行失败报错日志java.util.concurrent.ExecutionException:java.lang.reflect.InvocationTargetExceptionatjava.util.concurrent.FutureTask.report(FutureTask.java:122)atjava.util.concurrent.FutureTask.get(FutureTask.java:206)atco......
  • XXL-JOB及Cron表达式
    目录一、XXL-JOB简述二、搭建xxl-Job2.1执行初始化sql脚本2.2引入依赖2.3xxl-job配置2.4执行器组件2.5开发任务2.6访问调度中心三、Cron表达式一、XXL-JOB简述XXL-JOB是一个分布式任务调度平台;核心设计目标是学习简单、开发迅速、轻量级、易扩展部分特性:1......
  • oracle数据库---PL/SQL、存储函数、存储过程、触发器、定时器job、备份
    PL/SQL什么是PL/SQLPL/SQL(Procedure Language/SQL)是Oracle对sql语言的过程化扩展,指在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。把SQL语言的数据操纵能力与过程语言的数据处理能力结合起来,使得PLSQL面向过程但比过程语言简单......
  • PowerShell 实现删除指定路径X天前文件功能并添加定时JOB实例
    公司的POA服务器的E盘隔三差五就爆满,原因是数据库备份文件越来越大,现在已经大到需要高频清理的地步了十一前出现的这个问题,当时为了不专门在假期里某天特地去清理磁盘,想着一定要搞个定时JOB实现自动清理最后选用了PowerShell脚本实现新建一个txt文件,打开编辑内容如下:#设置要......
  • XXJ-JOB任务调度-快速入门-集成项目-动态创建任务
    XXJ-JOB任务调度官方文档:https://www.xuxueli.com/xxl-job/概述XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。文档地址中文文档一、快速入门依赖<dependency><group......
  • ESP32移植Openharmony设备开发---(3)任务调度
    任务调度官方文档:OpenAtomOpenHarmony基本概念从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,各任务的运行相互独立。OpenHarmonyLiteOS-M的任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。......