• ruoyi中xxl-job配置使用


    前言

    必须了解的概念

    1、调度中心

    ltkj-personnel-xxl-job-admin、或 xxl-job-admin为调度中心服务,是独立运行的任务管理后台。

    2、执行器

    xx应用,想使用定时任务功能,在有了调度中心的基础上,在xx应用的配置文件里,集成xxl-job的注册地址,如ltkj-personnel-admin、或ruoyi-admin应用。
    在这里插入图片描述

    环境搭建

    一、xxl-job环境搭建测试

    1、下载xxl-job源码

    Gitee:https://gitee.com/xuxueli0323/xxl-job

    2、执行SQL文件,生成对应表结构

    在这里插入图片描述

    #
    # XXL-JOB v2.3.0
    # Copyright (c) 2015-present, xuxueli.
    
    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', '示例执行器', 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
    • 118
    • 119
    3、修改xxl-job-admin服务的 application.properties数据库地址可直接启动

    在这里插入图片描述
    在这里插入图片描述

    至此调度中心服务配置,启动完成了--------------------------------------------------------- 。
    下面是具体业务应用中 集成xxl-job ,使用定时任务功能。
    1、修改 lxxj-personnel-admin 应用的对应环境的 application.yml
    # xxl-job配置
    xxl:
      job:
        admin:
          # 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
          addresses: http://172.18.101.191:8080/xxl-job-admin
        executor:
          # 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
          address: http://192.168.1.188:8888 
          # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
          appname: my-application-task
          # 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
          ip: 192.168.1.188
          # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
          port: 9999
          # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
          logpath: /Users/luoyu/Documents/log/xxl-job/jobhandler
        
           # 执行器通讯TOKEN [选填]:非空时启用;
           ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
    	   xxl.job.executor.logretentiondays=30
          accessToken:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    2、新建一个config目录创建XxlJobConfig类

    可以在ltj-personnnel-admin 具体应用下面,或代码隔离,在其子模块下面 ltk-personnel-job
    在这里插入图片描述
    在这里插入图片描述

    4、根据项目结构到对应的模块中创建测试Job任务
    /**
    * 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 xuxueli 2019-12-11 21:52:51 */ @Slf4j @Service public class SampleService { /** * 1、简单任务示例(Bean模式) */ @XxlJob("demoJobHandler") public void demoJobHandler() throws Exception { XxlJobHelper.log("XXL-JOB, Hello World."); for (int i = 0; i < 5; i++) { log.info("demoJobHandler 简单任务示例(Bean模式).....i = {}", i); XxlJobHelper.log("beat at:" + i); } // default success } /** * 2、分片广播任务 */ @XxlJob("shardingJobHandler") public void shardingJobHandler() throws Exception { // 分片参数 int shardIndex = XxlJobHelper.getShardIndex(); int shardTotal = XxlJobHelper.getShardTotal(); XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal); log.info("2 shardingJobHandler 分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal); // 业务逻辑 for (int i = 0; i < shardTotal; i++) { if (i == shardIndex) { XxlJobHelper.log("第 {} 片, 命中分片开始处理", i); log.info("2 shardingJobHandler 第 {} 片, 命中分片开始处理", i); } else { XxlJobHelper.log("第 {} 片, 忽略", i); log.info("2 shardingJobHandler 第 {} 片, 忽略", 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"); log.info("3 commandJobHandler 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() { log.info("init"); } public void destroy() { log.info("destory"); } }

    • 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
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241

    6、启动应用: 业务服务 lk-personnel-admin (作为执行器,会向调度中心注册暴露,以供调用)

    7、进入调度中心页面
    在这里插入图片描述

    8、创建执行器
    在这里插入图片描述

    9、创建调度任务 xxxxService类中的

    在这里插入图片描述

    在这里插入图片描述

    10、执行调度任务

    11、查询执行日志

    12、执行日志显示

    13、控制台显示

    (二)xxl-Job和Spring Boot集成

    1、导入依赖

    2、添加配置文件

    三、用户管理

    https://www.xuxueli.com/xxl-job/#%E6%AD%A5%E9%AA%A4%E4%B8%80%EF%BC%9A%E8%B0%83%E5%BA%A6%E4%B8%AD%E5%BF%83%E9%85%8D%E7%BD%AE%EF%BC%9A

  • 相关阅读:
    物联网LORA技术-SX1276/SX1277/SX1278-137MHz至1020MHz低功耗远距离收发器
    Spring的配置Bean的方式
    客户管理系统在选型过程中遇到的常见问题
    产品技术体系
    【C语言】动态内存管理 经典笔试题
    分布式对象存储
    移动端input输入时底部按钮被虚拟键盘顶上解决办法
    Js使用ffmpeg在视频中添加png或gif
    oppo前端开发一面
    .net core-利用PdfSharpCore和SkiaSharp.QrCode 添加PDF二维码页眉
  • 原文地址:https://blog.csdn.net/nalanxiaoxiao2011/article/details/134089696