xxl-Job详解(整合springboot)超详细

07-14 1322阅读

XXL-JOB简介

有兴趣的小伙伴可以去看一下他的官网:分布式任务调度平台XXL-JOB (xuxueli.com)

xxl-Job详解(整合springboot)超详细

XXL-JOB是什么

解释

XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。

为什么要叫 XXL 呢?答:是因为他的作者的名字叫许雪里,使用了名字的缩写

分布式任务调度平台是什么呢?答:一个定时任务实现方案

在平时的业务场景中,经常有一些场景需要使用定时任务,比如:

时间驱动的场景:某个时间点发送优惠券,发送短信等等。

批量处理数据:批量统计上个月的账单,统计上个月销售数据等等。

固定频率的场景:每隔5分钟需要执行一次。

所以定时任务在平时开发中并不少见,而且对于现在快速消费的时代,每天都需要发送各种推送,消息都需要依赖定时任务去完成.


为什么需要任务调度平台,而不用传统的 Timer 与 Quartz

在Java中,传统的定时任务实现方案,比如Timer,Quartz等都或多或少存在一些问题:

  • 不支持集群、不支持统计、没有管理平台、没有失败报警、没有监控等等而且在现在分布式的架构中,有一些场景需要分布式任务调度:
  • 同一个服务多个实例的任务存在互斥时,需要统一的调度。
  • 任务调度需要支持高可用、监控、故障告警。
  • 需要统一管理和追踪各个服务节点任务调度的结果,需要记录保存任务属性信息等。

    显然传统的定时任务已经不满足现在的分布式架构,所以需要一个分布式任务调度平台,目前比较主流的是elasticjob和xxl-job。

    为什么选择XXL-JOB,不选择elasticjob

    跟xxl-job不同的是,elasticjob是采用zookeeper实现分布式协调,实现任务高可用以及分片。

    • xxl-job环境依赖于mysql,elasticjob依赖于ZooKeeper,这也是最大的不同。
    • elasticjob是无中心化的,通过ZooKeeper的选举机制选举出主服务器,如果主服务器挂了,会重新选举新的主服务器。因此elasticjob具有良好的扩展性和可用性,但是使用和运维有一定的复杂.
    • xxl-job则相反,是通过一个中心式的调度平台,调度多个执行器执行任务,调度中心通过DB锁保证集群分布式调度的一致性,这样扩展执行器会增大DB的压力,但是如果实际上这里数据库只是负责任务的调度执行。但是如果没有大量的执行器的话和任务的情况,是不会造成数据库压力的。实际上大部分公司任务数,执行器并不多(虽然面试经常会问一些高并发的问题)。

      相对来说,xxl-job中心式的调度平台轻量级,开箱即用,操作简易,上手快,与SpringBoot有非常好的集成,而且监控界面就集成在调度中心,界面又简洁,对于企业维护起来成本不高,还有失败的邮件告警等等。这就使很多企业选择xxl-job做调度平台。

      学习之前必看,少走很多弯路

      我先讲一下xxl-job的运行原理(我自己的理解):

      xxl-job是一个网页,用来处理注册在里面的请求,并每过多长的时间(自己设置)就会传递一个值给springboot,这样就会出现一个问题:xxl-job要在局域网下才能连接成功。

      就会出现本地的服务(springboot)是连接不上服务器端(xxl-job)的

      为什么?

      在同一个网段下(本地),xxl-job可以给本地服务(springboot)发送服务;但如果xxl-job是在服务器上,那么你能跟他通信,但他不能给你通信,意思就是他ping你的ip是ping不通的

      解决方法1:

      先在本地做测试的环境(xxlJob和springboot服务都在本地),服务器上的也做一样的配置,本地把服务(springboot)打包后,上传服务器,那么两个服务器直接就可以建立联系,或者上传到同一服务器上,组成服务器的本地环境

      解决方法2:

      进入服务器上的xxl-job访问不了本地的,是因为本地不能被外网访问,那么就用内网穿透工具,让外网服务器可以访问本地端口就行


      安装XXL-JOB

      • 源码编译(Windows/Linux)

        一、源码编译(Windows)

        1、拉取源码:xxl-job: 一个分布式任务调度平台
        2、导入IDEA,查看一下目录

        xxl-Job详解(整合springboot)超详细

        3、初始化数据库,配置数据库连接信息(在本地导入上图中的sql文件,并把配置文件给改好)

        xxl-Job详解(整合springboot)超详细

        xxl-Job详解(整合springboot)超详细

        ### xxl-job, datasource
        spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
        spring.datasource.username=root
        spring.datasource.password=root
        spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
        

        application.properties配置文件最上方可以指定访问端口

        xxl-Job详解(整合springboot)超详细

        ### web
        server.port=8888
        server.servlet.context-path=/xxl-job-admin
        

        application.properties配置文件最下方可以指定访问令牌(可以随意设置)

        xxl-Job详解(整合springboot)超详细

        ### xxl-job, access token
        xxl.job.accessToken=Lv2023
        
        4.编译运行

        访问http://localhost:8888(自己设置的端口)/xxl-job-admin/toLogin

        进入管理页面。默认账号/密码:admin/123456

        xxl-Job详解(整合springboot)超详细

        二、源码编译(Linux)

        将配置好xxlJob连接信息的springBoot项目和配置好mysql连接信息的xxlJob项目, 打包成jar包

        (我的springBoot项目是使用jenkins进行打包发布的, 详情可以看这篇文章

        jenkins的安装与配置(超详细)

        springBoot项目配置xxlJob连接信息(我用的是开发和测试环境, 并且将配置信息放在job模块中)

        springBoot项目配置xxlJob连接信息

        SpringBoot配置详情可以看(本文章下方SpringBoot配置内容)

        #开发dev环境
        xxl:
          job:
            admin:
                #xxlJob访问地址
              addresses: http://ip地址:8888(访问端口)/xxl-job-admin
            #xxlJob访问令牌(在xxlJob配置文件中自行设置的)
            accessToken: Lv2023
            executor:
              appname: ${JOB_EXECUTOR_APP_NAME:xxl-job-executor-sample}
            	#xxlJob执行器地址
              ip: ${JOB_EXECUTOR_IP:127.0.0.1}
              port: 0
              # 日志地址
              logpath: /home/workspace/xxl-job/jobhandler
              # 日志保存时间
              logretentiondays: 30
        #测试test环境
        xxl:
          job:
            admin:
              addresses: http://ip地址:8888(访问端口)/xxl-job-admin
            accessToken: Lv2023
            executor:
              appname: ${JOB_EXECUTOR_APP_NAME:xxl-job-executor-sample}
              ip: ${JOB_EXECUTOR_IP:(执行器ip地址}
              port: 0
              logpath: /home/workspace/xxl-job/jobhandler
              logretentiondays: 30
        
        打包项目

        xxl-Job详解(整合springboot)超详细

        打开jar包目录, 导入到服务器中

        xxl-Job详解(整合springboot)超详细

        服务器端设置好jar存放目录并将jar包导入

        xxl-Job详解(整合springboot)超详细

        启动命令

        nohup java -jar xxl-job-admin-2.4.1-SNAPSHOT.jar >xxlJobLog.txt &

        解释: (后台运行 xxl-job-admin-2.4.1-SNAPSHOT.jar 这个jar包, 并在运行后生成xxlJobLog.txt日志文件)

        访问服务端xxlJob页面

        (服务器别忘开放安全组和防火墙端口)

        访问http://服务端xxlJob地址或域名:8888(自行设置的访问端口)/xxl-job-admin/toLogin

        默认账号/密码:admin/12345

        xxl-Job详解(整合springboot)超详细


        使用XXL-JOB(集成SpringBoot)

        (必须两个服务都在本地,或者都在服务器端)

        SpringBoot配置:

        一、导入maven依赖
                
                
                    com.xuxueli
                    xxl-job-core
                    2.3.1
                
        
        二、配置yam
        #开发dev环境
        xxl:
          job:
            admin:
                #xxlJob访问地址
              addresses: http://ip地址:8888(访问端口)/xxl-job-admin
            #xxlJob访问令牌(在xxlJob配置文件中自行设置的)
            accessToken: Lv2023
            executor:
            	#执行器名称
              appname: ${JOB_EXECUTOR_APP_NAME:xxl-job-executor-sample}
            	#xxlJob执行器地址
              ip: ${JOB_EXECUTOR_IP:127.0.0.1}
              port: 0
              # 日志地址
              logpath: /home/workspace/xxl-job/jobhandler
              # 日志保存时间
              logretentiondays: 30
        #测试test环境
        xxl:
          job:
            admin:
              addresses: http://ip地址:8888(访问端口)/xxl-job-admin
            accessToken: Lv2023
            executor:
              appname: ${JOB_EXECUTOR_APP_NAME:xxl-job-executor-sample}
              ip: ${JOB_EXECUTOR_IP:(执行器ip地址}
              port: 0
              logpath: /home/workspace/xxl-job/jobhandler
              logretentiondays: 30
        
        三、XxlJobConfig配置类
        package com.Lv.job.config;
        import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
        import lombok.extern.slf4j.Slf4j;
        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
        @Slf4j
        public class XxlJobConfig {
            private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
            @Value("${xxl.job.admin.addresses}")
            private String adminAddresses;
            @Value("${xxl.job.executor.appname}")
            private String appName;
            @Value("${xxl.job.executor.ip}")
            private String ip;
            @Value("${xxl.job.executor.port}")
            private int port;
            @Value("${xxl.job.accessToken}")
            private String accessToken;
            @Value("${xxl.job.executor.logpath}")
            private String logPath;
            @Value("${xxl.job.executor.logretentiondays}")
            private int logRetentionDays;
            @Bean
            public XxlJobSpringExecutor xxlJobExecutor() {
                log.info("\n>>>>>>>>>>> xxl-job config init.");
                XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
                xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
                xxlJobSpringExecutor.setAppname(appName);
                xxlJobSpringExecutor.setIp(ip);
                xxlJobSpringExecutor.setPort(port);
                xxlJobSpringExecutor.setAccessToken(accessToken);
                xxlJobSpringExecutor.setLogPath(logPath);
                xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
                logger.info("\n>>>>>>>>>>> xxl-job config , adminAddresses = {} , appName = {}",adminAddresses,appName);
                return xxlJobSpringExecutor;
            }
            /**
             * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
             *
             *      1、引入依赖:
             *          
             *             org.springframework.cloud
             *             spring-cloud-commons
             *             ${version}
             *         
             *
             *      2、配置文件,或者容器启动变量
             *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
             *
             *      3、获取IP
             *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
             */
        }
        
        四、Demo.java
        package com.Lv.job.business.Demo;
        import com.xxl.job.core.biz.model.ReturnT;
        import com.xxl.job.core.context.XxlJobHelper;
        import com.xxl.job.core.handler.annotation.XxlJob;
        import io.swagger.annotations.ApiModel;
        import org.springframework.stereotype.Component;
        @ApiModel("测试报表任务")
        @Component
        public class XxlDemoHandler {
            @XxlJob("DemoHandler")
            public void demo() throws Exception {
                XxlJobHelper.log("测试开始");
                String param = XxlJobHelper.getJobParam();
                System.out.println();
                System.out.println();
                System.out.println();
                System.out.println(param);
                System.out.println("测试完成!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                System.out.println();
                System.out.println();
                System.out.println();
                XxlJobHelper.log("测试开结束");
            }
        }
        

        XXL-JOB配置(与上文的yaml文件结合着看)

        一、配置执行器

        本地服务跑通后, 自动获取为127.0.0.1:9999(xxlJob默认执行器端口号)

        服务端(springBoot服务跑通后), 为自己设置的执行器地址和默认端口)

        xxl-Job详解(整合springboot)超详细

        如果不需要本地进行job的测试, 可以编辑执行器 -> 注册方式改为手动录入(将服务器的机器地址保留)

        xxl-Job详解(整合springboot)超详细

        xxl-Job详解(整合springboot)超详细

        二、配置任务管理(配合Demo.java看)Cron表达式放最后了

        xxl-Job详解(整合springboot)超详细

        三、测试

        xxl-Job详解(整合springboot)超详细

        执行后, 查看点击操作种的查询日志, 看日志信息, 是否执行成功,(如果没成功, 看报错信息进行更改)

        xxl-Job详解(整合springboot)超详细

        四、查看运行结果

        xxlJob执行日志

        xxl-Job详解(整合springboot)超详细

        或者看控制台中的日志

        xxl-Job详解(整合springboot)超详细

        xxl-Job详解(整合springboot)超详细

        springboot中Job模块执行日志

        xxl-Job详解(整合springboot)超详细

        五、Cron生成器

        (一般不需要自己写, 了解下即可)

        在线Cron表达式生成器

        Cron学习:

        Cron表达式简单学习


        遇到的问题

        XXLJOB登陆提示Attempted reconnect 3 times. Giving up

        org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
        ### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
        ### The error may exist in class path resource [mybatis-mapper/XxlJobUserMapper.xml]
        ### The error may involve com.xxl.job.admin.dao.XxlJobUserDao.loadByUserName
        ### The error occurred while executing a query
        ### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up
        

        xxl-Job详解(整合springboot)超详细

        SSL握手的问题

        解决办法;

        看了XXLJOB的启动日志发现, 是数据库连接时出现了SSL握手的问题,数据库连接使用了SSL,但握手失败引起的

        检查数据库连接参数:

        确保数据库连接参数正确。在你的配置中,spring.datasource.url中的连接字符串包含了SSL相关的配置。如果数据库并没有启用SSL,可以尝试将连接字符串修改为不使用SSL的版本。例如:

        spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
        

        这会将useSSL参数设置为false。

        检查数据库SSL配置:

        如果数据库确实使用SSL,确保数据库端的SSL配置正确。可能需要检查数据库配置文件,确保SSL证书和密钥的路径正确,并且数据库已正确配置为接受SSL连接。

        检查JDBC驱动版本:

        确保使用的MySQL JDBC驱动是最新的版本。你可以访问MySQL官方网站或者Maven中央仓库获取最新版本的MySQL驱动。在你的pom.xml或者Gradle构建文件中,确保以下类似的依赖:

        
            mysql
            mysql-connector-java
            最新版本
        
        

        如果你手动下载了JDBC驱动的JAR文件,确保它是最新版本。

        排除SSL问题:

        为了快速解决问题,你可以尝试在连接字符串中排除SSL,以验证问题是否与SSL握手有关。在spring.datasource.url中添加以下参数:

        spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
        

        useSSL=false禁用SSL,allowPublicKeyRetrieval=true允许获取公钥。

        检查网络和防火墙:

        确保服务器之间的网络连接正常,并且防火墙没有阻止数据库连接。

        尝试上述建议,并根据实际情况调整配置,以解决SSL握手问题。


        数据库配置SSL

        在MySQL服务器上,通过以下方法检查是否启用了SSL配置:

        查看MySQL配置文件:

        打开MySQL的配置文件,通常是my.cnf或my.ini文件。这个文件通常位于MySQL的安装目录下,也可能位于**/etc/目录下或/etc/mysql/或/etc/my.cnf.d/**目录中,。使用文本编辑器查看该文件,查找是否存在以下配置项:

        [mysqld]
        ssl-key=/path/to/server-key.pem
        ssl-cert=/path/to/server-cert.pem
        ssl-ca=/path/to/ca-cert.pem
        

        如果存在类似上述配置项,说明MySQL服务器启用了SSL。

        使用MySQL客户端检查:

        使用MySQL客户端连接到数据库,并执行以下SQL语句:

        SHOW VARIABLES LIKE 'have_ssl';
        

        如果结果中的Value列显示YES,则表示MySQL服务器启用了SSL。

        查看错误日志:

        MySQL的错误日志文件通常包含有关SSL配置的信息。在MySQL的配置文件中,你可以查找log-error参数指定的错误日志文件的位置。查看该文件,检查是否有SSL相关的信息,以及是否存在任何与SSL握手或证书相关的错误。

        通过命令行参数启动MySQL:

        如果MySQL服务器是通过命令行参数启动的,你可以检查启动命令中是否包含SSL相关的选项。例如:

        mysqld --ssl-key=/path/to/server-key.pem --ssl-cert=/path/to/server-cert.pem --ssl-ca=/path/to/ca-cert.pem
        

        如果命令中包含以上SSL相关的选项,说明MySQL服务器启用了SSL。

        查看MySQL状态信息:

        使用MySQL客户端连接到数据库,并执行以下SQL语句:

        SHOW STATUS LIKE 'Ssl_cipher';
        

        如果结果非空,表示SSL已经启用,并且显示了使用的SSL密码套件。


        执行器Online机器地址(注册节点)加倍问题

        发现服务启动后, 执行器机器地址变成了双倍, 相同ip地址, 但是端口号一个9999,一个10000

        原因:

        XxlJobSpringExecutor本身是实现了SmartInitializingSingleton接口,

        afterSingletonsInstantiated方法本身就调用了父类(XxlJobExecutor)的start方法,

        如果再执行initMethod指定的start,就会导致调用两次start方法(初始化bean一次,bean初始化完又调用一次),xxl 执行器就会注册两次导致执行器注册数量不对

        xxl-Job详解(整合springboot)超详细

        解决思路:

        Bean之前是这样的,多添加了一个initMethod,去掉即可

        @Bean(initMethod = "start", destroyMethod = "destroy")

         @Bean
            public XxlJobSpringExecutor xxlJobExecutor() {
                log.info("\n>>>>>>>>>>> xxl-job config init.");
                XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
                xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
                xxlJobSpringExecutor.setAppname(appName);
                xxlJobSpringExecutor.setIp(ip);
                xxlJobSpringExecutor.setPort(port);
                xxlJobSpringExecutor.setAccessToken(accessToken);
                xxlJobSpringExecutor.setLogPath(logPath);
                xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
                logger.info("\n>>>>>>>>>>> xxl-job config , adminAddresses = {} , appName = {}",adminAddresses,appName);
                return xxlJobSpringExecutor;
            }
        

        详细的可以看下方文章:

        https://blog.csdn.net/qq_42651904/article/details/120555995?spm=1001.2014.3001.5506

        执行器报错相关问题

        xxl-job remoting error(connect timed out), for url : http://xxxx:端口/run

        xxl-Job详解(整合springboot)超详细

        解决办法:

        将xxlJob应用和jar包服务所在的机器开启xxl_job访问地址端口和执行器默认端口9999的安全组和防火墙端口 (我的访问端口是8888)

        xxl-Job详解(整合springboot)超详细

        xxl-job remoting error(拒绝连接 (Connection refused), for url : http://xxxx:端口/run

        xxl-Job详解(整合springboot)超详细

        解决办法:

        如果xxl-job执行器自动注册有机器, 还是被拒绝连接(可能是执行器机器所在的问题)

        查看两台服务器

        1.xxl-job所在机器 和 jar包程序所在机器的9999端口是否被监听

        xxl-Job详解(整合springboot)超详细

        发现xxl-job应用所在的机器, 没有监听执行器的9999端口, 导致连接不上, 一直被拒绝.

        需要我们在jar包的配置中更改xxl-job的执行器机器为能被监听的那台机器的ip

        xxl-Job详解(整合springboot)超详细

        执行器ip更改为监听9999端口的机器ip, 重新发布,启动jar包即可解决

        部分文章内容引自

        https://blog.csdn.net/qq_57581439/article/details/128319069

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]