mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-10 19:00:53 +08:00
feat: 新增任务调度模块
SnailJob(灵活,可靠和快速的分布式任务重试和分布式任务调度平台)
This commit is contained in:
@@ -25,6 +25,25 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成器插件(后续会改造为独立插件) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-generator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 任务调度插件(后续会改造为独立插件) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-job</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Liquibase(用于管理数据库版本,跟踪、管理和应用数据库变化) -->
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
@@ -36,18 +55,6 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码生成器插件(后续会改造为独立插件) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-generator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-admin-system</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.controller.schedule;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import top.continew.admin.job.model.query.JobQuery;
|
||||
import top.continew.admin.job.model.req.JobReq;
|
||||
import top.continew.admin.job.model.req.JobStatusReq;
|
||||
import top.continew.admin.job.model.resp.JobResp;
|
||||
import top.continew.admin.job.service.JobService;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
import top.continew.starter.extension.crud.util.ValidateGroup;
|
||||
import top.continew.starter.log.core.annotation.Log;
|
||||
import top.continew.starter.web.model.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务 API
|
||||
*
|
||||
* @author KAI
|
||||
* @author Charles7c
|
||||
* @since 2024/6/25 22:24
|
||||
*/
|
||||
@Tag(name = " 任务 API")
|
||||
@Validated
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/schedule/job")
|
||||
public class JobController {
|
||||
|
||||
private final JobService baseService;
|
||||
|
||||
@Operation(summary = "分页查询任务列表", description = "分页查询任务列表")
|
||||
@SaCheckPermission("schedule:job:list")
|
||||
@GetMapping
|
||||
public R<PageResp<JobResp>> page(JobQuery query) {
|
||||
return R.ok(baseService.page(query));
|
||||
}
|
||||
|
||||
@Operation(summary = "新增任务", description = "新增任务")
|
||||
@SaCheckPermission("schedule:job:add")
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody JobReq req) {
|
||||
return baseService.add(req) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Operation(summary = "修改任务", description = "修改任务")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("schedule:job:update")
|
||||
@PutMapping("/{id}")
|
||||
public R<Void> update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody JobReq req, @PathVariable Long id) {
|
||||
return baseService.update(req, id) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Operation(summary = "修改任务状态", description = "修改任务状态")
|
||||
@SaCheckPermission("schedule:job:update")
|
||||
@PatchMapping("/{id}/status")
|
||||
public R<Void> updateStatus(@Validated @RequestBody JobStatusReq req, @PathVariable Long id) {
|
||||
return baseService.updateStatus(req, id) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Operation(summary = "删除任务", description = "删除任务")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("schedule:job:delete")
|
||||
@DeleteMapping("/{id}")
|
||||
public R<Void> delete(@PathVariable Long id) {
|
||||
return baseService.delete(id) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Operation(summary = "执行任务", description = "执行任务")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("schedule:job:trigger")
|
||||
@PostMapping("/trigger/{id}")
|
||||
public R<Void> trigger(@PathVariable Long id) {
|
||||
return baseService.trigger(id) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Log(ignore = true)
|
||||
@Operation(summary = "查询任务分组列表", description = "查询任务分组列表")
|
||||
@SaCheckPermission("schedule:job:list")
|
||||
@GetMapping("/group")
|
||||
public R<List<String>> listGroup() {
|
||||
List<String> groupList = baseService.listGroup();
|
||||
return R.ok(groupList);
|
||||
}
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.controller.schedule;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import top.continew.admin.job.model.JobInstanceLogPageResult;
|
||||
import top.continew.admin.job.model.query.JobInstanceLogQuery;
|
||||
import top.continew.admin.job.model.query.JobLogQuery;
|
||||
import top.continew.admin.job.model.query.JobInstanceQuery;
|
||||
import top.continew.admin.job.model.resp.JobLogResp;
|
||||
import top.continew.admin.job.model.resp.JobInstanceResp;
|
||||
import top.continew.admin.job.service.JobLogService;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
import top.continew.starter.web.model.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务日志 API
|
||||
*
|
||||
* @author KAI
|
||||
* @author Charles7c
|
||||
* @since 2024/6/27 22:24
|
||||
*/
|
||||
@Tag(name = " 任务日志 API")
|
||||
@Validated
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/schedule/log")
|
||||
public class JobLogController {
|
||||
|
||||
private final JobLogService baseService;
|
||||
|
||||
@Operation(summary = "分页查询任务日志列表", description = "分页查询任务日志列表")
|
||||
@SaCheckPermission("schedule:log:list")
|
||||
@GetMapping
|
||||
public R<PageResp<JobLogResp>> page(JobLogQuery query) {
|
||||
return R.ok(baseService.page(query));
|
||||
}
|
||||
|
||||
@Operation(summary = "停止任务", description = "停止任务")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("schedule:log:stop")
|
||||
@PostMapping("/stop/{id}")
|
||||
public R<Void> stop(@PathVariable Long id) {
|
||||
return baseService.stop(id) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Operation(summary = "重试任务", description = "重试任务")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@SaCheckPermission("schedule:log:retry")
|
||||
@PostMapping("/retry/{id}")
|
||||
public R<Void> retry(@PathVariable Long id) {
|
||||
return baseService.retry(id) ? R.ok() : R.fail();
|
||||
}
|
||||
|
||||
@Operation(summary = "查询任务实例列表", description = "查询任务实例列表")
|
||||
@SaCheckPermission("schedule:log:list")
|
||||
@GetMapping("/instance")
|
||||
public R<List<JobInstanceResp>> listInstance(JobInstanceQuery query) {
|
||||
return R.ok(baseService.listInstance(query));
|
||||
}
|
||||
|
||||
@Operation(summary = "分页查询任务实例日志列表", description = "分页查询任务实例日志列表")
|
||||
@SaCheckPermission("schedule:log:list")
|
||||
@GetMapping("/instance/log")
|
||||
public R<JobInstanceLogPageResult> pageInstanceLog(JobInstanceLogQuery query) {
|
||||
return R.ok(baseService.pageInstanceLog(query));
|
||||
}
|
||||
}
|
@@ -286,3 +286,51 @@ spring.servlet:
|
||||
## 头像支持格式配置
|
||||
avatar:
|
||||
support-suffix: jpg,jpeg,png,gif
|
||||
|
||||
--- ### Snail Job 配置
|
||||
snail-job:
|
||||
# 分组名
|
||||
group: continew-admin
|
||||
# 客户端地址(默认自动获取本机 IP)
|
||||
#host: 127.0.0.1
|
||||
# 客户端端口(默认:1789)
|
||||
port: 1789
|
||||
# 名称空间 ID
|
||||
namespace: 764d604ec6fc45f68cd92514c40e9e1a
|
||||
# 令牌
|
||||
token: SJ_Wyz3dmsdbDOkDujOTSSoBjGQP1BMsVnj
|
||||
## 服务端配置
|
||||
server:
|
||||
# 服务端地址
|
||||
url: http://127.0.0.1:8001/snail-job
|
||||
# 服务端用户名
|
||||
username: admin
|
||||
# 服务端密码
|
||||
password: admin
|
||||
# 服务端地址,若服务端集群部署则此处配置域名
|
||||
host: 127.0.0.1
|
||||
# 服务端端口号
|
||||
port: 1788
|
||||
## 重试数据批量上报滑动窗口配置
|
||||
retry:
|
||||
reportSlidingWindow:
|
||||
# 窗口期单位
|
||||
chrono-unit: SECONDS
|
||||
# 窗口期时间长度
|
||||
duration: 10
|
||||
# 总量窗口期阈值
|
||||
total-threshold: 50
|
||||
# 窗口数量预警
|
||||
window-total-threshold: 150
|
||||
## 调度线程池配置
|
||||
dispatcherThreadPool:
|
||||
# 核心线程数
|
||||
corePoolSize: 16
|
||||
# 最大线程数
|
||||
maximumPoolSize: 16
|
||||
# 线程存活时间
|
||||
keepAliveTime: 1
|
||||
# 时间单位
|
||||
timeUnit: SECONDS
|
||||
# 队列容量
|
||||
queueCapacity: 10000
|
@@ -283,3 +283,51 @@ spring.servlet:
|
||||
## 头像支持格式配置
|
||||
avatar:
|
||||
support-suffix: jpg,jpeg,png,gif
|
||||
|
||||
--- ### Snail Job 配置
|
||||
snail-job:
|
||||
# 分组名
|
||||
group: continew_admin
|
||||
# 客户端地址(默认自动获取本机 IP)
|
||||
#host: 127.0.0.1
|
||||
# 客户端端口(默认:1789)
|
||||
port: 1789
|
||||
# 名称空间 ID
|
||||
namespace: 764d604ec6fc45f68cd92514c40e9e1a
|
||||
# 令牌
|
||||
token: SJ_Wyz3dmsdbDOkDujOTSSoBjGQP1BMsVnj
|
||||
## 服务端配置
|
||||
server:
|
||||
# 服务端地址
|
||||
url: http://127.0.0.1:8001/snail-job
|
||||
# 服务端用户名
|
||||
username: admin
|
||||
# 服务端密码
|
||||
password: admin
|
||||
# 服务端地址,若服务端集群部署则此处配置域名
|
||||
host: 127.0.0.1
|
||||
# 服务端端口号
|
||||
port: 1788
|
||||
## 重试数据批量上报滑动窗口配置
|
||||
retry:
|
||||
reportSlidingWindow:
|
||||
# 窗口期单位
|
||||
chrono-unit: SECONDS
|
||||
# 窗口期时间长度
|
||||
duration: 10
|
||||
# 总量窗口期阈值
|
||||
total-threshold: 50
|
||||
# 窗口数量预警
|
||||
window-total-threshold: 150
|
||||
## 调度线程池配置
|
||||
dispatcherThreadPool:
|
||||
# 核心线程数
|
||||
corePoolSize: 16
|
||||
# 最大线程数
|
||||
maximumPoolSize: 16
|
||||
# 线程存活时间
|
||||
keepAliveTime: 1
|
||||
# 时间单位
|
||||
timeUnit: SECONDS
|
||||
# 队列容量
|
||||
queueCapacity: 10000
|
@@ -122,10 +122,12 @@ mybatis-plus:
|
||||
mapper-locations: classpath*:/mapper/**/*Mapper.xml
|
||||
# 类型别名扫描包配置
|
||||
type-aliases-package: ${project.base-package}.**.model
|
||||
## MyBatis 配置
|
||||
configuration:
|
||||
# MyBatis 自动映射策略
|
||||
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
|
||||
auto-mapping-behavior: PARTIAL
|
||||
## 全局配置
|
||||
global-config:
|
||||
banner: true
|
||||
db-config:
|
||||
|
@@ -172,4 +172,19 @@ INSERT INTO `sys_storage`
|
||||
(`id`, `name`, `code`, `type`, `access_key`, `secret_key`, `endpoint`, `bucket_name`, `domain`, `description`, `is_default`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
|
||||
VALUES
|
||||
(1, '开发环境', 'local_dev', 2, NULL, NULL, NULL, 'C:/continew-admin/data/file/', 'http://localhost:8000/file', '本地存储', b'1', 1, 1, 1, NOW(), NULL, NULL),
|
||||
(2, '生产环境', 'local_prod', 2, NULL, NULL, NULL, '../data/file/', 'http://api.continew.top/file', '本地存储', b'0', 2, 2, 1, NOW(), NULL, NULL);
|
||||
(2, '生产环境', 'local_prod', 2, NULL, NULL, NULL, '../data/file/', 'http://api.continew.top/file', '本地存储', b'0', 2, 2, 1, NOW(), NULL, NULL);
|
||||
|
||||
-- changeset Kai:3.2-1
|
||||
INSERT INTO `sys_menu` (`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `redirect`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`)
|
||||
VALUES
|
||||
(4000, '任务调度', 0, 1, '/schedule', 'Schedule', 'Layout', '/schedule/job', 'schedule', b'0', b'0', b'0', NULL, 997, 1, 1, NOW(), NULL, NULL),
|
||||
(4010, '任务管理', 4000, 2, '/schedule/job', 'ScheduleJob', 'schedule/job/index', NULL, 'select-all', b'0', b'0', b'0', NULL, 1, 1, 1, NOW(), NULL, NULL),
|
||||
(4011, '查看', 4010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:list', 1, 1, 1, NOW(), NULL, NULL),
|
||||
(4012, '新增', 4010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:add', 2, 1, 1, NOW(), NULL, NULL),
|
||||
(4013, '修改', 4010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:update', 3, 1, 1, NOW(), NULL, NULL),
|
||||
(4014, '删除', 4010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:delete', 4, 1, 1, NOW(), NULL, NULL),
|
||||
(4015, '执行', 1010, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:job:trigger', 5, 1, 1, NOW(), NULL, NULL),
|
||||
(4020, '任务日志', 4000, 2, '/schedule/log', 'ScheduleLog', 'schedule/log/index', NULL, 'find-replace', b'0', b'0', b'0', NULL, 2, 1, 1, NOW(), NULL, NULL),
|
||||
(4021, '查看', 4020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:list', 1, 1, 1, NOW(), NULL, NULL),
|
||||
(4022, '停止', 4020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:stop', 2, 1, 1, NOW(), NULL, NULL),
|
||||
(4023, '重试', 4020, 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'schedule:log:retry', 3, 1, 1, NOW(), NULL, NULL);
|
Reference in New Issue
Block a user