From 64ca6f44781162b542753aefb652e27dc39480cf Mon Sep 17 00:00:00 2001 From: Xiang Date: Tue, 6 Jan 2026 15:30:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=8A=A8=E6=80=81=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9A=84cron=E5=92=8C=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 48 +++++++++++ .../admin/server/XxzJobFetchController.java | 29 +++++++ .../admin/service/ITaskConfigService.java | 3 + .../service/impl/TaskConfigServiceImpl.java | 5 ++ xservice-quartz-core/pom.xml | 5 ++ .../xiang/core/quartz/annotation/XxzJob.java | 10 +-- .../xiang/core/quartz/api/AdminJobClient.java | 14 ++++ .../quartz/api/HttpAdminJobClientImpl.java | 45 ++++++++++ .../core/quartz/boostrap/JobBootstrap.java | 32 ++++++- .../xiang/core/quartz/model/JobConfigDO.java | 84 +++++++++++++++++++ .../core/quartz/model/XxzJobProperties.java | 5 ++ .../xiang/core/quartz/scanner/JobScanner.java | 4 +- .../springboot/schedule/TestXxzJob1.java | 2 +- .../src/main/resources/application.yml | 1 + 14 files changed, 275 insertions(+), 12 deletions(-) create mode 100644 readme.md create mode 100644 xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/server/XxzJobFetchController.java create mode 100644 xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/AdminJobClient.java create mode 100644 xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/HttpAdminJobClientImpl.java create mode 100644 xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/JobConfigDO.java diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..264954c --- /dev/null +++ b/readme.md @@ -0,0 +1,48 @@ +# Xxz-job任务调度系统 + +### (一) + +### (二)版本控制 + +#### (1)v1.0版本-master分支上 + +1. 设计Xxz-job注解以及EnableXxzJob注解,编写xxz-job注解扫描器以及注解执行器,本机单机执行任务。 + +```java +// 第一版Xxz-job注解内容 +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface XxzJob { + + /** + * bean的名称 + * + * @return + */ + String name(); + + /** + * cron调度方法 + * @return + */ + String cron(); + + boolean enabled() default true; + /** + * 是否支持多机分布式运行 + * 若为false:每台机器都会执行一次 + * 若为true:仅一台机器会执行 + * + * @return + */ + boolean distributed() default true; +} +``` + +第一版XxzJob注解仅支持单机,并且cron固定的方式进行设计,能够将任务根据cron正常启动。 + +#### (2)v1.1版本-feat/schedule_v1_0106 + +1. 动态获取定时任务的cron和开关 +1. \ No newline at end of file diff --git a/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/server/XxzJobFetchController.java b/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/server/XxzJobFetchController.java new file mode 100644 index 0000000..b0ac82a --- /dev/null +++ b/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/server/XxzJobFetchController.java @@ -0,0 +1,29 @@ +package com.xiang.app.quartz.admin.server; + +import com.xiang.app.quartz.admin.domain.entity.JobConfigDO; +import com.xiang.app.quartz.admin.service.ITaskConfigService; +import com.xiang.xservice.basic.common.resp.Result; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @Author: xiang + * @Date: 2026-01-06 15:05 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/open/quartz/fetch") +public class XxzJobFetchController { + + private final ITaskConfigService taskConfigService; + @GetMapping("/list") + public Result list(@RequestParam("appName") String appName) { + List jobsByAppName = taskConfigService.getJobsByAppName(appName); + return Result.success(jobsByAppName); + } +} diff --git a/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/ITaskConfigService.java b/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/ITaskConfigService.java index 3cd2e1b..7c307b0 100644 --- a/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/ITaskConfigService.java +++ b/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/ITaskConfigService.java @@ -1,5 +1,6 @@ package com.xiang.app.quartz.admin.service; +import com.xiang.app.quartz.admin.domain.entity.JobConfigDO; import com.xiang.app.quartz.admin.domain.req.TaskRegisterRequest; import java.util.List; @@ -23,4 +24,6 @@ public interface ITaskConfigService { * @return */ boolean registerTasks(List request); + + List getJobsByAppName(String appName); } diff --git a/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/impl/TaskConfigServiceImpl.java b/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/impl/TaskConfigServiceImpl.java index 53c9495..e7c2a6f 100644 --- a/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/impl/TaskConfigServiceImpl.java +++ b/xservice-quartz-admin/src/main/java/com/xiang/app/quartz/admin/service/impl/TaskConfigServiceImpl.java @@ -67,6 +67,11 @@ public class TaskConfigServiceImpl implements ITaskConfigService { return true; } + @Override + public List getJobsByAppName(String appName) { + return quartzConfigManage.selectByAppName(appName); + } + private static void putDataIntoDo(TaskRegisterRequest item, JobConfigDO jobConfigDO, String applicationName) { jobConfigDO.setApplicationName(applicationName); jobConfigDO.setApplicationAddress(item.getApplicationAddress()); diff --git a/xservice-quartz-core/pom.xml b/xservice-quartz-core/pom.xml index 1fb80df..0b59d29 100644 --- a/xservice-quartz-core/pom.xml +++ b/xservice-quartz-core/pom.xml @@ -25,6 +25,11 @@ xmc-common 1.0 + + com.xiang.starter + xmc-http-starter + 1.0 + com.xiang.starter xmc-cache-starter diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/annotation/XxzJob.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/annotation/XxzJob.java index be690d3..f40f733 100644 --- a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/annotation/XxzJob.java +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/annotation/XxzJob.java @@ -22,11 +22,11 @@ public @interface XxzJob { */ String name(); - /** - * cron调度方法 - * @return - */ - String cron(); +// /** +// * cron调度方法 +// * @return +// */ +// String cron(); boolean enabled() default true; /** diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/AdminJobClient.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/AdminJobClient.java new file mode 100644 index 0000000..7a533ac --- /dev/null +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/AdminJobClient.java @@ -0,0 +1,14 @@ +package com.xiang.core.quartz.api; + +import com.xiang.core.quartz.model.JobConfigDO; + +import java.util.List; + +/** + * @Author: xiang + * @Date: 2026-01-06 15:10 + */ +public interface AdminJobClient { + + List fetchJobByAppName(String appName); +} diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/HttpAdminJobClientImpl.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/HttpAdminJobClientImpl.java new file mode 100644 index 0000000..ece15c0 --- /dev/null +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/api/HttpAdminJobClientImpl.java @@ -0,0 +1,45 @@ +package com.xiang.core.quartz.api; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.xiang.core.quartz.model.JobConfigDO; +import com.xiang.core.quartz.model.XxzJobProperties; +import com.xiang.xmc.service.http.helper.HttpHelper; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @Author: xiang + * @Date: 2026-01-06 15:11 + */ +@Component +@RequiredArgsConstructor +public class HttpAdminJobClientImpl implements AdminJobClient{ + + private final XxzJobProperties xxzJobProperties; + @Override + public List fetchJobByAppName(String appName) { + String address = xxzJobProperties.getAdminAddress(); + address = address + "/open/quartz/fetch/list"; + Map params = Maps.newHashMap(); + params.put("appName", appName); + String resp = HttpHelper.doGet(address, null, params); + if (StringUtils.isNotBlank(resp)) { + JSONObject jsonObject = JSON.parseObject(resp); + if (Objects.nonNull(jsonObject)) { + String data = JSON.toJSONString(jsonObject.get("data")); + if (StringUtils.isNotBlank(data)) { + return JSON.parseArray(data, JobConfigDO.class); + } + } + } + return Lists.newArrayList(); + } +} diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/boostrap/JobBootstrap.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/boostrap/JobBootstrap.java index d27834f..28294c1 100644 --- a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/boostrap/JobBootstrap.java +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/boostrap/JobBootstrap.java @@ -1,14 +1,22 @@ package com.xiang.core.quartz.boostrap; +import com.xiang.core.quartz.api.AdminJobClient; import com.xiang.core.quartz.holder.JobDefinitionHolder; -import com.xiang.core.quartz.model.JobDefinition; +import com.xiang.core.quartz.model.JobConfigDO; +import com.xiang.core.quartz.model.XxzJobProperties; import com.xiang.core.quartz.schedule.JobScheduler; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + /** * @Author: xiang * @Date: 2026-01-06 09:50 @@ -19,13 +27,29 @@ public class JobBootstrap implements ApplicationRunner { @Autowired private JobScheduler scheduler; + @Autowired + private AdminJobClient adminJobClient; + @Autowired + private XxzJobProperties xxzJobProperties; @Override public void run(ApplicationArguments args) { + List jobConfigDOS = adminJobClient.fetchJobByAppName(xxzJobProperties.getAppName()); + if (CollectionUtils.isEmpty(jobConfigDOS)) { + return; + } + Map map = jobConfigDOS.stream().collect(Collectors.toMap(JobConfigDO::getBeanName, Function.identity(), (a, b) -> a)); JobDefinitionHolder.getAll() - .stream() - .filter(JobDefinition::isEnabled) - .forEach(scheduler::schedule); + .forEach(item -> { + if (map.containsKey(item.getName())) { + JobConfigDO jobConfigDO = map.get(item.getName()); + if (jobConfigDO.getJobSwitch() == 1) { + item.setCron(jobConfigDO.getCron()); + item.setEnabled(jobConfigDO.getJobSwitch() == 1); + scheduler.schedule(item); + } + } + }); } } diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/JobConfigDO.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/JobConfigDO.java new file mode 100644 index 0000000..0acd3e1 --- /dev/null +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/JobConfigDO.java @@ -0,0 +1,84 @@ +package com.xiang.core.quartz.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * @Author: xiang + * @Date: 2025-12-30 09:42 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName("xmc_quartz_config") +public class JobConfigDO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + /** + * 应用名称 + */ + private String applicationName; + + /** + * 应用地址 + */ + private String applicationAddress; + + /** + * 定时任务名称 + */ + private String beanName; + + /** + * 任务执行调度时间 + */ + private String cron; + + /** + * 类名 + */ + private String clazz; + + /** + * 方法 + */ + private String method; + + /** + * 任务开关 + * 0:关闭 1:开启 + */ + private Integer jobSwitch; + + /** + * 删除标识(0:未删除 1:已删除) + */ + private Integer delFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 修改时间 + */ + private LocalDateTime updateTime; + + /** + * 上次执行时间 + */ + private LocalDateTime lastRunningTime; +} diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/XxzJobProperties.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/XxzJobProperties.java index 31b834c..255f23a 100644 --- a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/XxzJobProperties.java +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/model/XxzJobProperties.java @@ -20,4 +20,9 @@ public class XxzJobProperties { * DB刷新任务间隔(毫秒) */ private int refreshInterval = 5000; + + /** + * 调度中心地址 + */ + private String adminAddress; } diff --git a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/scanner/JobScanner.java b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/scanner/JobScanner.java index d937de8..5f59639 100644 --- a/xservice-quartz-core/src/main/java/com/xiang/core/quartz/scanner/JobScanner.java +++ b/xservice-quartz-core/src/main/java/com/xiang/core/quartz/scanner/JobScanner.java @@ -50,8 +50,8 @@ public class JobScanner implements SmartInitializingSingleton { job.setDistributed(xxzJob.distributed()); job.setBean(bean); job.setMethod(method); - job.setEnabled(xxzJob.enabled()); - job.setCron(xxzJob.cron()); +// job.setEnabled(); +// job.setCron(xxzJob.cron()); JobDefinitionHolder.register(job); } } diff --git a/xservice-quartz-sample/src/main/java/com/xiang/app/quartz/sample/springboot/schedule/TestXxzJob1.java b/xservice-quartz-sample/src/main/java/com/xiang/app/quartz/sample/springboot/schedule/TestXxzJob1.java index 2f2a6c3..05aaaa7 100644 --- a/xservice-quartz-sample/src/main/java/com/xiang/app/quartz/sample/springboot/schedule/TestXxzJob1.java +++ b/xservice-quartz-sample/src/main/java/com/xiang/app/quartz/sample/springboot/schedule/TestXxzJob1.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Component; @Component public class TestXxzJob1 { - @XxzJob(name = "TestXxzJob", cron = "0/1 * * * * ? ", enabled = true) + @XxzJob(name = "TestXxzJob") public void test() { log.info("任务调度开始"); } diff --git a/xservice-quartz-sample/src/main/resources/application.yml b/xservice-quartz-sample/src/main/resources/application.yml index 5767634..6a11831 100644 --- a/xservice-quartz-sample/src/main/resources/application.yml +++ b/xservice-quartz-sample/src/main/resources/application.yml @@ -1,5 +1,6 @@ xxz-job: app-name: springboot-quartz-test + admin-address: http://127.0.0.1:30030 spring: main: