• Docker安装xxl-job并整合到SpringBoot项目


    1. 创建数据库

    执行如下SQL语句创建相关表

    CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_general_ci;
    use `xxl_job`;
    
    SET NAMES utf8mb4;
    CREATE TABLE `xxl_job_info` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
      `job_desc` varchar(255) NOT NULL,
      `add_time` datetime DEFAULT NULL,
      `update_time` datetime DEFAULT NULL,
      `author` varchar(64) DEFAULT NULL COMMENT '作者',
      `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
      `schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
      `schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
      `misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
      `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
      `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
      `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
      `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
      `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
      `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
      `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
      `glue_source` mediumtext COMMENT 'GLUE源代码',
      `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
      `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
      `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
      `trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
      `trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
      `trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_log` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
      `job_id` int(11) NOT NULL COMMENT '任务,主键ID',
      `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
      `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
      `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
      `executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
      `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
      `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
      `trigger_code` int(11) NOT NULL COMMENT '调度-结果',
      `trigger_msg` text COMMENT '调度-日志',
      `handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
      `handle_code` int(11) NOT NULL COMMENT '执行-状态',
      `handle_msg` text COMMENT '执行-日志',
      `alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
      PRIMARY KEY (`id`),
      KEY `I_trigger_time` (`trigger_time`),
      KEY `I_handle_code` (`handle_code`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_log_report` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
      `running_count` int(11) NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
      `suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
      `fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
      `update_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_logglue` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `job_id` int(11) NOT NULL COMMENT '任务,主键ID',
      `glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
      `glue_source` mediumtext COMMENT 'GLUE源代码',
      `glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
      `add_time` datetime DEFAULT NULL,
      `update_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_registry` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `registry_group` varchar(50) NOT NULL,
      `registry_key` varchar(255) NOT NULL,
      `registry_value` varchar(255) NOT NULL,
      `update_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_group` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
      `title` varchar(12) NOT NULL COMMENT '执行器名称',
      `address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
      `address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
      `update_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(50) NOT NULL COMMENT '账号',
      `password` varchar(50) NOT NULL COMMENT '密码',
      `role` tinyint(4) NOT NULL COMMENT '角色:0-普通用户、1-管理员',
      `permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
      PRIMARY KEY (`id`),
      UNIQUE KEY `i_username` (`username`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE `xxl_job_lock` (
      `lock_name` varchar(50) NOT NULL COMMENT '锁名称',
      PRIMARY KEY (`lock_name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' );
    INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '测试任务1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', '2018-11-03 22:21:31', '');
    INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
    INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');
    
    commit;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117

    各表作用如下

    • xxl_job_lock:任务调度锁表;
    • xxl_job_group:执行器信息表,维护任务执行器信息;
    • xxl_job_info:调度扩展信息表: 用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等;
    • xxl_job_log:调度日志表: 用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等;
    • xxl_job_log_report:调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到;
    • xxl_job_logglue:任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能;
    • xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息;
    • xxl_job_user:系统用户表;

    2. Docker配置xxl-job-admin

    2.1 拉取镜像

    执行命令:

    docker pull xuxueli/xxl-job-admin:2.4.0
    
    • 1

    2.2 创建容器并运行

    执行命令:

    docker run -d -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.150.101:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 --spring.datasource.username=root --spring.datasource.password=123 --xxl.job.accessToken=tianji" \
    -p 28080:8080 \
    -v /usr/local/src/docker/xxl-job/applogs:/data/applogs \
    --name my-xxl-job \
    --privileged=true \
    xuxueli/xxl-job-admin:2.4.0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如果启动失败,检查数据源配置是否有效、端口是否被占用等;

    参数说明:

    • -e PARAMS:MySQL数据源;
    • --privileged=true :容器内的root拥有真正的root权限;
    • --restart=always:Docker服务启动时容器也随之启动;
    • -v :日志目录挂载;
    • -p :端口 左边宿主机 右边容器 ;
    • --xxl.job.accessToken:执行器通讯TOKEN,要和调度中心服务部署配置的accessToken一致,要不然无法连接注册。

    在浏览器访问地址:http://192.168.150.101:28080/xxl-job-admin

    在这里插入图片描述

    这里的192.168.150.101是安装xxl-job-admin的设备ip,记得防火墙开放端口;

    默认的账密:admin/123456

    在这里插入图片描述

    3. SpringBoot整合xxl-job

    3.1 修改YML配置文件

    在application.yml配置文件添加如下内容:

    tj:
      xxl-job:
          admin:
            # 调度中心服务部署的地址
            addresses: http://192.168.150.101:28080/xxl-job-admin
          # 执行器通讯TOKEN,要和调度中心服务部署配置的accessToken一致,要不然无法连接注册
          accessToken: tianji
          executor:
            # 执行器AppName
            appName: xxl-job-test
            # 执行器注册 [选填]
            address:
            ip:
            #执行器端口号: 小于等于0则自动获取 默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
            port: 0
            # 执行器运行日志文件存储磁盘路径 [选填] 需要对该路径拥有读写权限;为空则使用默认路径;
            logPath: D:/test
            # 执行器日志文件保存天数 [选填] 过期日志自动清理, 限制值大于等于3时生效  否则, 如-1, 关闭自动清理功能
            logRetentionDays: 15
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.2 代码整合

    引入依赖,版本需要与xxl-job-admin一致:

            
            <dependency>
                <groupId>com.xuxueligroupId>
                <artifactId>xxl-job-coreartifactId>
                <version>2.4.0version>        
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    配置xxl-job:

    新建XxlJobProperties.java,用于读取yml配置

    package com.example.xxljobdemo.config;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @Data
    @ConfigurationProperties(prefix = "tj.xxl-job")
    public class XxlJobProperties {
    
        private String accessToken;
        private Admin admin;
        private Executor executor;
    
        @Data
        public static class Admin {
            private String addresses;
        }
    
        @Data
        public static class Executor {
            private String appName;
            private String address;
            private String ip;
            private Integer port;
            private String logPath;
            private Integer logRetentionDays;
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    新建XxlJobProperties.java,用于新增xxl-job执行器

    package com.example.xxljobdemo.config;
    
    import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.util.StringUtils;
    
    @Slf4j
    @Configuration
    @EnableConfigurationProperties(XxlJobProperties.class)
    public class XxlJobConfig {
    
        @Bean
        public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties prop) {
            log.info(">>>>>>>>>>> xxl-job config init.");
            XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
            XxlJobProperties.Admin admin = prop.getAdmin();
            if (admin != null && StringUtils.hasLength(admin.getAddresses())) {
                xxlJobSpringExecutor.setAdminAddresses(admin.getAddresses());
            }
            XxlJobProperties.Executor executor = prop.getExecutor();
            if (executor != null) {
                if (executor.getAppName() != null)
                    xxlJobSpringExecutor.setAppname(executor.getAppName());
                if (executor.getIp() != null)
                    xxlJobSpringExecutor.setIp(executor.getIp());
                if (executor.getPort() != null)
                    xxlJobSpringExecutor.setPort(executor.getPort());
                if (executor.getLogPath() != null)
                    xxlJobSpringExecutor.setLogPath(executor.getLogPath());
                if (executor.getLogRetentionDays() != null)
                    xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());
            }
            if (prop.getAccessToken() != null)
                xxlJobSpringExecutor.setAccessToken(prop.getAccessToken());
            log.info(">>>>>>>>>>> xxl-job config end.");
            return xxlJobSpringExecutor;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3.3 建立测试任务

    package com.example.xxljobdemo.task;
    
    import com.xxl.job.core.handler.annotation.XxlJob;
    import org.springframework.stereotype.Component;
    
    /**
     * @author: hong.jian
     * @date 2024-03-27 20:17
     */
    @Component
    public class XxlJobTask {
        @XxlJob("testXxlJobHandler")
        public void testXxlJobHandler() throws Exception {
            System.out.println("hello---->xxl-job");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    启动springboot项目,在xxl-job-admin执行器管理手动新增执行器,因为xxl-job不会自动新增执行器,名称要与yml配置文件中的appName一致,这里我写的xxl-job-test;

    在这里插入图片描述

    新建成功后,等一会,点击查看能看到注册成功了

    在这里插入图片描述

    xxl-job-admin执行器管理手动新增任务,

    在这里插入图片描述

    其中比较关键的几个配置:

    • 调度配置:也就是什么时候执行,一般选择cron表达式
    • 任务配置:采用BEAN模式,指定JobHandler,这里指定的就是在项目中@XxlJob注解中的任务名称
    • 路由策略:就是指如果有多个任务执行器,该由谁执行?这里支持的策略非常多:
      • 在这里插入图片描述

    路由策略说明:

    • FIRST(第一个):固定选择第一个执行器;
    • LAST(最后一个):固定选择最后一个执行器;
    • ROUND(轮询):在线的执行器按照轮询策略选择一个执行
    • RANDOM(随机):随机选择在线的执行器;
    • CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台执行器,且所有任务均匀散列在不同执行器上。
    • LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的执行器优先被选举;
    • LEAST_RECENTLY_USED(最近最久未使用):最久未使用的执行器优先被选举;
    • FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的执行器选定为目标执行器并发起调度;
    • BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的执行器选定为目标执行器并发起调度;
    • SHARDING_BROADCAST(分片广播):广播触发对应集群中所有执行器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务

    3.4 测试

    点击操作-执行一次,进行测试

    在这里插入图片描述

    调度日志界面可以看到执行成功

    在这里插入图片描述

    如果执行失败,可以在此查看错误信息方便排查

    4. 总结

    xxl-job需要手动新增执行器和任务,踩坑

  • 相关阅读:
    与时俱进「风险系统保障质量之路」非同寻常
    【SQL】Mysql 时区设置解决--20230928
    k8s存储学习 emptyDir 卷
    .....
    paramiko 3
    python用selenium网页模拟时无法定位元素解决方法1
    “Node.js 包已不值得信任”
    文心一言 vs GPT-4 —— 全面横向比较
    代码随想录算法训练营第三天 | 第454题.四数相加II|Python中的dict和C里面的map相同点和不同点总结
    c/c++语言算法技巧汇总大复习2
  • 原文地址:https://blog.csdn.net/Mr_Richard/article/details/137099871