From 750cc3308791483ce63dea2efe84868cc605dab4 Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: Wed, 7 Aug 2019 17:00:14 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20spring-boot-demo-task-xxl-job?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring-boot-demo-task-xxl-job/.gitignore | 25 ++++ spring-boot-demo-task-xxl-job/pom.xml | 14 ++ .../SpringBootDemoTaskXxlJobApplication.java | 20 +++ .../task/xxl/job/config/XxlJobConfig.java | 42 ++++++ .../xxl/job/config/props/XxlJobProps.java | 67 +++++++++ .../controller/ManualOperateController.java | 138 ++++++++++++++++++ .../xkcoding/task/xxl/job/task/DemoTask.java | 39 +++++ .../src/main/resources/application.yml | 20 ++- 8 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 spring-boot-demo-task-xxl-job/.gitignore create mode 100644 spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/SpringBootDemoTaskXxlJobApplication.java create mode 100644 spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/XxlJobConfig.java create mode 100644 spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/props/XxlJobProps.java create mode 100644 spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/controller/ManualOperateController.java create mode 100644 spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/task/DemoTask.java diff --git a/spring-boot-demo-task-xxl-job/.gitignore b/spring-boot-demo-task-xxl-job/.gitignore new file mode 100644 index 0000000..82eca33 --- /dev/null +++ b/spring-boot-demo-task-xxl-job/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-demo-task-xxl-job/pom.xml b/spring-boot-demo-task-xxl-job/pom.xml index d9859ad..d222bc1 100644 --- a/spring-boot-demo-task-xxl-job/pom.xml +++ b/spring-boot-demo-task-xxl-job/pom.xml @@ -20,6 +20,7 @@ UTF-8 UTF-8 1.8 + 2.1.0 @@ -28,11 +29,24 @@ spring-boot-starter-web + + org.springframework.boot + spring-boot-configuration-processor + true + + mysql mysql-connector-java + + + com.xuxueli + xxl-job-core + ${xxl-job.version} + + org.springframework.boot spring-boot-starter-test diff --git a/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/SpringBootDemoTaskXxlJobApplication.java b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/SpringBootDemoTaskXxlJobApplication.java new file mode 100644 index 0000000..72d3530 --- /dev/null +++ b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/SpringBootDemoTaskXxlJobApplication.java @@ -0,0 +1,20 @@ +package com.xkcoding.task.xxl.job; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + *

+ * 启动器 + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-07 10:13 + */ +@SpringBootApplication +public class SpringBootDemoTaskXxlJobApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootDemoTaskXxlJobApplication.class, args); + } +} diff --git a/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/XxlJobConfig.java b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/XxlJobConfig.java new file mode 100644 index 0000000..368a1c3 --- /dev/null +++ b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/XxlJobConfig.java @@ -0,0 +1,42 @@ +package com.xkcoding.task.xxl.job.config; + +import com.xkcoding.task.xxl.job.config.props.XxlJobProps; +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + *

+ * xxl-job 自动装配 + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-07 10:20 + */ +@Slf4j +@Configuration +@EnableConfigurationProperties(XxlJobProps.class) +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class XxlJobConfig { + private final XxlJobProps xxlJobProps; + + @Bean(initMethod = "start", destroyMethod = "destroy") + public XxlJobSpringExecutor xxlJobExecutor() { + log.info(">>>>>>>>>>> xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(xxlJobProps.getAdmin().getAddress()); + xxlJobSpringExecutor.setAccessToken(xxlJobProps.getAccessToken()); + xxlJobSpringExecutor.setAppName(xxlJobProps.getExecutor().getAppName()); + xxlJobSpringExecutor.setIp(xxlJobProps.getExecutor().getIp()); + xxlJobSpringExecutor.setPort(xxlJobProps.getExecutor().getPort()); + xxlJobSpringExecutor.setLogPath(xxlJobProps.getExecutor().getLogPath()); + xxlJobSpringExecutor.setLogRetentionDays(xxlJobProps.getExecutor().getLogRetentionDays()); + + return xxlJobSpringExecutor; + } + +} diff --git a/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/props/XxlJobProps.java b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/props/XxlJobProps.java new file mode 100644 index 0000000..944a8f0 --- /dev/null +++ b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/config/props/XxlJobProps.java @@ -0,0 +1,67 @@ +package com.xkcoding.task.xxl.job.config.props; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + *

+ * xxl-job 配置 + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-07 10:25 + */ +@Data +@ConfigurationProperties(prefix = "xxl.job") +public class XxlJobProps { + /** + * 调度中心配置 + */ + private XxlJobAdminProps admin; + + /** + * 执行器配置 + */ + private XxlJobExecutorProps executor; + + /** + * 与调度中心交互的accessToken + */ + private String accessToken; + + @Data + public static class XxlJobAdminProps { + /** + * 调度中心地址 + */ + private String address; + } + + @Data + public static class XxlJobExecutorProps { + /** + * 执行器名称 + */ + private String appName; + + /** + * 执行器 IP + */ + private String ip; + + /** + * 执行器端口 + */ + private int port; + + /** + * 执行器日志 + */ + private String logPath; + + /** + * 执行器日志保留天数,-1 + */ + private int logRetentionDays; + } +} diff --git a/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/controller/ManualOperateController.java b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/controller/ManualOperateController.java new file mode 100644 index 0000000..4df1ee7 --- /dev/null +++ b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/controller/ManualOperateController.java @@ -0,0 +1,138 @@ +package com.xkcoding.task.xxl.job.controller; + +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.google.common.collect.Maps; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import com.xxl.job.core.glue.GlueTypeEnum; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +/** + *

+ * 手动操作 xxl-job + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-07 14:58 + */ +@Slf4j +@RestController +@RequestMapping("/xxl-job") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class ManualOperateController { + private final static String baseUri = "http://127.0.0.1:18080/xxl-job-admin"; + private final static String JOB_INFO_URI = "/jobinfo"; + private final static String JOB_GROUP_URI = "/jobgroup"; + + /** + * 任务组列表,xxl-job叫做触发器列表 + */ + @GetMapping("/group") + public String xxlJobGroup() { + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_GROUP_URI + "/list").execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + + /** + * 分页任务列表 + * @param page 当前页,第一页 -> 0 + * @param size 每页条数,默认10 + * @return 分页任务列表 + */ + @GetMapping("/list") + public String xxlJobList(Integer page, Integer size) { + Map jobInfo = Maps.newHashMap(); + jobInfo.put("start", page != null ? page : 0); + jobInfo.put("length", size != null ? size : 10); + jobInfo.put("jobGroup", 2); + jobInfo.put("triggerStatus", -1); + + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_INFO_URI + "/pageList").form(jobInfo).execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + + /** + * 测试手动保存任务 + */ + @GetMapping("/add") + public String xxlJobAdd() { + Map jobInfo = Maps.newHashMap(); + jobInfo.put("jobGroup", 2); + jobInfo.put("jobCron", "0 0/1 * * * ? *"); + jobInfo.put("jobDesc", "手动添加的任务"); + jobInfo.put("author", "admin"); + jobInfo.put("executorRouteStrategy", "ROUND"); + jobInfo.put("executorHandler", "demoTask"); + jobInfo.put("executorParam", "手动添加的任务的参数"); + jobInfo.put("executorBlockStrategy", ExecutorBlockStrategyEnum.SERIAL_EXECUTION); + jobInfo.put("glueType", GlueTypeEnum.BEAN); + + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_INFO_URI + "/add").form(jobInfo).execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + + /** + * 测试手动触发一次任务 + */ + @GetMapping("/trigger") + public String xxlJobTrigger() { + Map jobInfo = Maps.newHashMap(); + jobInfo.put("id", 4); + jobInfo.put("executorParam", JSONUtil.toJsonStr(jobInfo)); + + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_INFO_URI + "/trigger").form(jobInfo).execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + + /** + * 测试手动删除任务 + */ + @GetMapping("/remove") + public String xxlJobRemove() { + Map jobInfo = Maps.newHashMap(); + jobInfo.put("id", 4); + + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_INFO_URI + "/remove").form(jobInfo).execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + + /** + * 测试手动停止任务 + */ + @GetMapping("/stop") + public String xxlJobStop() { + Map jobInfo = Maps.newHashMap(); + jobInfo.put("id", 4); + + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_INFO_URI + "/stop").form(jobInfo).execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + + /** + * 测试手动停止任务 + */ + @GetMapping("/start") + public String xxlJobStart() { + Map jobInfo = Maps.newHashMap(); + jobInfo.put("id", 4); + + HttpResponse execute = HttpUtil.createGet(baseUri + JOB_INFO_URI + "/start").form(jobInfo).execute(); + log.info("【execute】= {}", execute); + return execute.body(); + } + +} diff --git a/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/task/DemoTask.java b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/task/DemoTask.java new file mode 100644 index 0000000..f3dc935 --- /dev/null +++ b/spring-boot-demo-task-xxl-job/src/main/java/com/xkcoding/task/xxl/job/task/DemoTask.java @@ -0,0 +1,39 @@ +package com.xkcoding.task.xxl.job.task; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.IJobHandler; +import com.xxl.job.core.handler.annotation.JobHandler; +import com.xxl.job.core.log.XxlJobLogger; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + *

+ * 测试定时任务 + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-07 10:15 + */ +@Slf4j +@Component +@JobHandler("demoTask") +public class DemoTask extends IJobHandler { + + /** + * execute handler, invoked when executor receives a scheduling request + * + * @param param 定时任务参数 + * @return 执行状态 + * @throws Exception 任务异常 + */ + @Override + public ReturnT execute(String param) throws Exception { + // 可以动态获取传递过来的参数,根据参数不同,当前调度的任务不同 + log.info("【param】= {}", param); + XxlJobLogger.log("demo task run at : {}", DateUtil.now()); + return RandomUtil.randomInt(1, 11) % 2 == 0 ? SUCCESS : FAIL; + } +} diff --git a/spring-boot-demo-task-xxl-job/src/main/resources/application.yml b/spring-boot-demo-task-xxl-job/src/main/resources/application.yml index a02fbde..7e5714f 100644 --- a/spring-boot-demo-task-xxl-job/src/main/resources/application.yml +++ b/spring-boot-demo-task-xxl-job/src/main/resources/application.yml @@ -1,4 +1,22 @@ server: port: 8080 servlet: - context-path: /demo \ No newline at end of file + context-path: /demo +xxl: + job: + # 执行器通讯TOKEN [选填]:非空时启用; + access-token: + admin: + # 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; + address: http://localhost:18080/xxl-job-admin + executor: + # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + app-name: spring-boot-demo-task-xxl-job-executor + # 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"; + ip: + # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + port: 9999 + # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + log-path: logs/spring-boot-demo-task-xxl-job/task-log + # 执行器日志保存天数 [选填] :值大于3时生效,启用执行器Log文件定期清理功能,否则不生效; + log-retention-days: -1