xxl-job,使命调度中央快速上手

打印 上一主题 下一主题

主题 861|帖子 861|积分 2585

前言

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

进入 xxl-job官网,里面有更具体的教程 XXL-JOB官网
1、下载源码
  1. git clone http://gitee.com/xuxueli0323/xxl-job
复制代码
通过IDEA打开后目录如下:

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

“调度数据库初始化SQL脚本” 位置为:
  1. `/xxl-job/doc/db/tables_xxl_job.sql`
复制代码
没错,你得执行这个sql文件到你的数据库中,执行完后 会有如下库和表出现在数据库中

3、项目构造


  • xxl-job-admin:调度中央
  • xxl-job-core:公共依赖
  • xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)

    •     :xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,本文章以这种方式介绍,官方推荐该方式;
    •     :xxl-job-executor-sample-frameless:无框架版本;

好了~,到这一步你的XXL—JOB算是装好了,下一步让我们来启动它

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


  • 调度中央项目:xxl-job-admin  《超关键,起的就是这玩意儿》
  • 作用:统一管理使命调度平台上调度使命,负责触发调度执行,并且提供使命管理平台。
先修改一下调度中央xxl-job-admin的配置文件。
  1. `/xxl-job/xxl-job-admin/src/main/resources/application.properties`
复制代码
主要修改数据库为本身的刚才执行sql的库
  1. ### xxl-job, datasource
  2. spring.datasource.url=jdbc:mysql://123.45.678.90:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
  3. spring.datasource.username=xxx用户
  4. spring.datasource.password=xxx密码
  5. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
复制代码
然后启动项目
  1. `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依赖;
  1. <dependency>
  2.     <groupId>com.xuxueli</groupId>
  3.     <artifactId>xxl-job-core</artifactId>
  4.     <version>${project.parent.version}</version>
  5. </dependency>
复制代码
2、执行器配置

执行器配置,配置文件地址:
  1. /xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties
复制代码
执行器配置,配置内容说明:
  1. # web port
  2. server.port=8081
  3. # no web
  4. #spring.main.web-environment=false
  5. # log config
  6. logging.config=classpath:logback.xml
  7. ### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
  8. ### 指向调度中心的地址
  9. xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
  10. ### xxl-job, access token
  11. xxl.job.accessToken=default_token
  12. ### xxl-job executor appname 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
  13. ### 执行器分组名称,关系到会注册到哪个组里
  14. xxl.job.executor.appname=learn-xxl-job
  15. ### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
  16. xxl.job.executor.address=
  17. ### xxl-job executor server-info
  18. xxl.job.executor.ip=
  19. xxl.job.executor.port=9999
  20. ### xxl-job executor log-path
  21. xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
  22. ### xxl-job executor log-retention-days
  23. xxl.job.executor.logretentiondays=30
复制代码
主要就是xxl.job.admin.addresses 和 xxl.job.executor.appname 这俩,第一个必须指向正确的调度中央地址
3、创建启动配置文件

因xxl-job没有使用spring-boot-starter,需自行将配置类注入到spring容器中。
  1. import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. /**
  8. * xxl-job config
  9. *
  10. * @author xuxueli 2017-04-28
  11. */
  12. @Configuration
  13. public class XxlJobConfig {
  14.     private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
  15.         //对应配置文件
  16.     @Value("${xxl.job.admin.addresses}")
  17.     private String adminAddresses;
  18.     @Value("${xxl.job.accessToken}")
  19.     private String accessToken;
  20.     @Value("${xxl.job.executor.appname}")
  21.     private String appname;
  22.     @Value("${xxl.job.executor.address}")
  23.     private String address;
  24.     @Value("${xxl.job.executor.ip}")
  25.     private String ip;
  26.     @Value("${xxl.job.executor.port}")
  27.     private int port;
  28.     @Value("${xxl.job.executor.logpath}")
  29.     private String logPath;
  30.     @Value("${xxl.job.executor.logretentiondays}")
  31.     private int logRetentionDays;
  32.     @Bean
  33.     public XxlJobSpringExecutor xxlJobExecutor() {
  34.         logger.info(">>>>>>>>>>> xxl-job config init.");
  35.         XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
  36.         xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
  37.         xxlJobSpringExecutor.setAppname(appname);
  38.         xxlJobSpringExecutor.setAddress(address);
  39.         xxlJobSpringExecutor.setIp(ip);
  40.         xxlJobSpringExecutor.setPort(port);
  41.         xxlJobSpringExecutor.setAccessToken(accessToken);
  42.         xxlJobSpringExecutor.setLogPath(logPath);
  43.         xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
  44.         return xxlJobSpringExecutor;
  45.     }
  46.     /**
  47.      * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
  48.      *
  49.      *      1、引入依赖:
  50.      *          <dependency>
  51.      *             <groupId>org.springframework.cloud</groupId>
  52.      *             <artifactId>spring-cloud-commons</artifactId>
  53.      *             <version>${version}</version>
  54.      *         </dependency>
  55.      *
  56.      *      2、配置文件,或者容器启动变量
  57.      *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
  58.      *
  59.      *      3、获取IP
  60.      *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
  61.      */
  62. }
复制代码
然后启动执行器,成功注册后,在调度中央可以看到

四、编写一个定时使命

1、创建一个使命调度

注意@XxlJob(“sendSMS”)注解中的sendSMS,即使命的唯一名称,之后执行使命调度将会使用。
  1. // 显示在调度中心日志的内容
  2. XxlJobHelper.log("无参数执行一个定时/指定任务");
  3. // 获取任务参数
  4. XxlJobHelper.getJobParam();
  5. // 用于在任务执行失败时向调度中心报告失败信息。调度中心会记录任务的失败状态,并可以根据配置进行相应的处理(如重试、告警等)。
  6. XxlJobHelper.handleFail("参数传递异常");
复制代码
  1. import com.xxl.job.core.context.XxlJobHelper;
  2. import com.xxl.job.core.handler.annotation.XxlJob;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * @author Cyf
  8. * @ Date: 2024/12/6 下午5:23
  9. */
  10. @Component
  11. public class MyJob {
  12.     public static final Logger log = LoggerFactory.getLogger(MyJob.class);
  13.    
  14. //          可使用@Resource/@Autowire注入执行器里中的其他服务
  15. //    @Autowired
  16. //    private UserService userService;
  17.     /**
  18.      * 无需参数传递
  19.      * @throws Exception
  20.      */
  21.     @XxlJob("sendSMS")
  22.     public void sendSMS() throws Exception {
  23.         
  24.         // 记录任务开始的日志
  25.         //只会显示再项目日志中
  26.         log.info("slf4j的框架");
  27.         //只会显示在xxl-job的日志中
  28.         XxlJobHelper.log("无参数执行一个定时/指定任务");
  29.         
  30.     }
  31.     /**
  32.      * 单个参数传递
  33.      * @throws Exception
  34.      */
  35.     @XxlJob("oneParameter")
  36.     public void sendMessage() throws Exception {
  37.         XxlJobHelper.log("单个任务参数为:" + XxlJobHelper.getJobParam());
  38.     }
  39.     /**
  40.      * 多个参数,应用 , 分割
  41.      * @throws Exception
  42.      */
  43.     @XxlJob("moreParameters")
  44.     public void sendMessage2() throws Exception {
  45.         try {
  46.             // 获取参数
  47.             String param = XxlJobHelper.getJobParam();
  48.             String[] methodParams = param.split(",");
  49.             XxlJobHelper.log("参数1为:" + methodParams[0] + ",参数2为" + methodParams[1]);
  50.         }catch (Exception e){
  51.             XxlJobHelper.handleFail("参数传递异常");
  52.         }
  53.     }
  54. }
复制代码
2、 xxl-job-admin中添加使命

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

3、执行使命


4、检察执行日志


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

可以通过Spring Aop拦截@XxlJob注解,去处置惩罚一些通用业务逻辑。
例如追加TraceId 进行日志定位
  1. import com.xxl.job.core.context.XxlJobHelper;
  2. import com.xxl.job.core.handler.annotation.XxlJob;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.aspectj.lang.ProceedingJoinPoint;
  5. import org.aspectj.lang.annotation.Around;
  6. import org.aspectj.lang.annotation.Aspect;
  7. import org.aspectj.lang.annotation.Pointcut;
  8. import org.slf4j.MDC;
  9. import org.springframework.core.annotation.Order;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.util.StopWatch;
  12. import java.io.PrintWriter;
  13. import java.io.StringWriter;
  14. import java.time.LocalDateTime;
  15. import java.util.UUID;
  16. /**
  17. * @author 为每个执行器增加traceId
  18. */
  19. @Slf4j
  20. @Order(1)
  21. @Aspect
  22. @Component
  23. public class XxlJobAspect {
  24.     @Pointcut("@annotation(com.xxl.job.core.handler.annotation.XxlJob)")
  25.     public void pointCut() {
  26.     }
  27.     @Around("pointCut() && @annotation(xxlJob)")
  28.     public Object doAround(ProceedingJoinPoint point, XxlJob xxlJob) {
  29.         String traceId = UUID.randomUUID().toString();
  30.         MDC.put("traceId", traceId);
  31.         String jobName = xxlJob.value();
  32.         StopWatch sw = new StopWatch();
  33.         sw.start();
  34.         log.info("定时任务[{}]开始,开始时间:{},输入参数:{}", jobName, LocalDateTime.now(), XxlJobHelper.getJobParam());
  35.         Object proceed;
  36.         try {
  37.             proceed = point.proceed();
  38.         } catch (Throwable e) {
  39.             log.warn("定时任务[{}]执行失败", jobName, e);
  40.             failure(e, traceId);
  41.             return null;
  42.         }
  43.         sw.stop();
  44.         log.info("定时任务[{}]结束!执行时间:{} ms", jobName, sw.getTotalTimeMillis());
  45.         success(traceId);
  46.         return proceed;
  47.     }
  48.     private void failure(Throwable e, String traceId) {
  49.         //将异常信息输出到xxl-job日志中
  50.         XxlJobHelper.handleFail("traceId=" + traceId + ",
  51. exception=" + getStackTrace(e));
  52.         MDC.remove("traceId");
  53.     }
  54.     private void success(String traceId) {
  55.         XxlJobHelper.handleSuccess("traceId=" + traceId);
  56.         MDC.remove("traceId");
  57.     }
  58.     /**
  59.      * 该方法来捕获异常的堆栈跟踪信息,并将其转换为字符串
  60.      * @param e 异常信息
  61.      * @return 堆栈跟踪字符串
  62.      */
  63.     private String getStackTrace(Throwable e) {
  64.         StringWriter stringWriter = new StringWriter();
  65.         PrintWriter printWriter = new PrintWriter(stringWriter);
  66.         e.printStackTrace(printWriter);
  67.         return stringWriter.toString();
  68.     }
  69. }
复制代码
在日志中添加TraceId,快速定位使命链路
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration debug="false" scan="true" scanPeriod="1 seconds">
  3.     <contextName>logback</contextName>
  4.     <property name="log.path" value="/data/applogs/xxl-job/xxl-job-executor-sample-springboot.log"/>
  5.    
  6.     <property name="PATTERN" value="%d{HH:mm:ss.SSS} %contextName [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n" />
  7.     <appender name="STDOUT" >
  8.         <encoder>
  9.             <pattern>${PATTERN}</pattern>
  10.         </encoder>
  11.     </appender>
  12.     <appender name="file" >
  13.         <file>${log.path}</file>
  14.         <rollingPolicy >
  15.             <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
  16.         </rollingPolicy>
  17.         <encoder>
  18.             <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
  19.             </pattern>
  20.         </encoder>
  21.     </appender>
  22.     <root level="info">
  23.         <appender-ref ref="file"/>
  24.         
  25.         <appender-ref ref="STDOUT"/>
  26.     </root>
  27. </configuration>
复制代码
然后重启项目,再次执行使命将打印如下日志
  1. 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,输入参数:
  2. 18:23:05.259 logback [xxl-job, JobThread-9-1733566985234] [531a6504-13bc-4bc6-91de-ff64b235110d] INFO  c.x.j.e.service.jobhandler.MyJob - slf4j的框架
  3. 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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用多少眼泪才能让你相信

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表