Compare commits
20 Commits
master-jdk
...
dev
Author | SHA1 | Date | |
---|---|---|---|
8ac38bef71 | |||
![]() |
7eb1c1efdc | ||
![]() |
01909eb7b3 | ||
![]() |
7e81fe9b73 | ||
![]() |
384007f7ff | ||
![]() |
0e45a51fd6 | ||
![]() |
df4b88550f | ||
![]() |
dfe66f6ba2 | ||
![]() |
93016523cc | ||
![]() |
499ecc13e5 | ||
![]() |
b04a938372 | ||
![]() |
d98c7ddcb9 | ||
![]() |
b76cf9efa0 | ||
![]() |
72599676e1 | ||
![]() |
503c401e09 | ||
![]() |
04b6ba9d4a | ||
![]() |
64ac13a1fd | ||
![]() |
05c944557e | ||
![]() |
caca8a90a6 | ||
![]() |
36ec3bb214 |
42
README.md
42
README.md
@ -1,8 +1,6 @@
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.easyretry.com">
|
||||
<img alt="Easy-Retry-Logo" src="doc/images/logo.png" width="350px">
|
||||
<a href="https://snailjob.opensnail.com/">
|
||||
<img alt="SnailJob-Logo" src="https://snailjob.opensnail.com/logo.svg" width="200px">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -10,17 +8,25 @@
|
||||
🔥🔥🔥 致力提高分布式业务系统一致性的分布式重试平台
|
||||
</p>
|
||||
|
||||
# JDK 支持
|
||||
|
||||
| JDK版本 | 对应分支 |
|
||||
|-------|-----------------------------------------------------------------------------|
|
||||
| ≥ 17 | [master](https://gitee.com/opensnail/snail-job-demo/tree/master/) |
|
||||
| 8 | [master-jdk8](https://gitee.com/opensnail/snail-job-demo/tree/master-jdk8/) |
|
||||
|
||||
# 🌸 简介
|
||||
|
||||
在当前广泛流行的分布式系统中,确保系统数据的一致性和正确性是一项重大挑战。为了解决分布式事务问题,涌现了许多理论和业务实践,其中BASE理论是目前业界广泛接受的分布式一致性理论。<br/>
|
||||
基于BASE理论,采用柔性事务并优先保障系统的可用性和数据的最终一致性已逐渐成为技术共识。<br/>
|
||||
为了确保分布式服务的可用性和数据一致性,并防止由于网络抖动、连接超时等问题导致短时不可用的情况,根据"墨菲定律",在核心流程中增加重试和数据核对校验的动作成为提高系统鲁棒性常用的技术方案。<br/>
|
||||
在此背景下EasyRetry应运而生。EasyRetry是一款致力提高分布式业务系统一致性的分布式重试平台。它提供了控制台任务观测、可配置的重试策略、重试后执行回调以及丰富地告警配置等功能。通过这些手段,可以对异常数据进行全面监测和回放,从而在确保系统高可用性的同时,大大提升数据的一致性。<br/>
|
||||
|
||||
# 🌼 重试方案对比
|
||||

|
||||
为了确保分布式服务的可用性和数据一致性,并防止由于网络抖动、连接超时等问题导致短时不可用的情况,根据"墨菲定律"
|
||||
,在核心流程中增加重试和数据核对校验的动作成为提高系统鲁棒性常用的技术方案。<br/>
|
||||
在此背景下SnailJob应运而生。SnailJob是一款致力提高分布式业务系统一致性的分布式重试平台。它提供了控制台任务观测、可配置的重试策略、重试后执行回调以及丰富地告警配置等功能。通过这些手段,可以对异常数据进行全面监测和回放,从而在确保系统高可用性的同时,大大提升数据的一致性。<br/>
|
||||
|
||||
# 🍀 特性
|
||||
Easy-RETRY 是一个针对业务系统重试流量的治理平台,其自身具有高可用高性能高负载的特点,服务特性有:
|
||||
|
||||
SnailJob 是一个针对业务系统重试流量的治理平台,其自身具有高可用高性能高负载的特点,服务特性有:
|
||||
|
||||
+ 支持千万级别的重试流量分派
|
||||
+ 支持流量容量扩容,自动识别并处理
|
||||
+ 支持流量处理节点水平扩容
|
||||
@ -29,32 +35,34 @@ Easy-RETRY 是一个针对业务系统重试流量的治理平台,其自身具
|
||||
+ 打包上报,支持高并发业务场景
|
||||
+ 加密通讯,保障信息安全
|
||||
|
||||
# 🌺 业务场景
|
||||
- https://www.easyretry.com/pages/406a68/
|
||||
# 后台预览地址
|
||||
|
||||
# 流量管理平台预览
|
||||
地址: <http://preview.easyretry.com/>
|
||||
账号: admin
|
||||
密码: admin
|
||||
地址: <https://preview.snailjob.opensnail.com/>
|
||||
|
||||
## 特别用户
|
||||
<a href="http://aizuda.com/?from=mp"></a>
|
||||
|
||||
<a href="http://aizuda.com/?from=mp"></a>
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [字节跳动: 如何优雅地重试](https://juejin.cn/post/6914091859463634951)
|
||||
- [这款分布式重试组件,治好了我的重试强迫症!](https://juejin.cn/post/7249607108043145274)
|
||||
- [系统简介](https://www.easyretry.com/pages/d1d1da/)
|
||||
- [架构与功能](https://www.easyretry.com/pages/540554/)
|
||||
|
||||
## 原理
|
||||
|
||||
- [场景应用](https://www.easyretry.com/pages/406a68/)
|
||||
- [HelloWorld](https://www.easyretry.com/pages/da9ecc/)
|
||||
|
||||
## 应用实例
|
||||
|
||||
- [easy-retry-demo](https://gitee.com/zhangyutongxue/easy-retry-demo)
|
||||
|
||||
## 期望
|
||||
|
||||
欢迎提出更好的意见,帮助完善 Easy-Retry
|
||||
|
||||
## 版权
|
||||
|
||||
[Apache-2.0](https://gitee.com/aizuda/easy-retry/blob/master/LICENSE)
|
||||
|
23
pom.xml
23
pom.xml
@ -5,18 +5,19 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.3.5</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>example1</artifactId>
|
||||
<groupId>com.opensnail</groupId>
|
||||
<artifactId>snailjob-demo</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>example</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<name>SnailJob-Demo</name>
|
||||
<description>Demo project for SnailJob</description>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<snailjob.version>1.5.0-beta1</snailjob.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -44,17 +45,17 @@
|
||||
<dependency>
|
||||
<groupId>com.aizuda</groupId>
|
||||
<artifactId>snail-job-client-starter</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>${snailjob.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aizuda</groupId>
|
||||
<artifactId>snail-job-client-retry-core</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>${snailjob.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aizuda</groupId>
|
||||
<artifactId>snail-job-client-job-core</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>${snailjob.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.aviator</groupId>
|
||||
@ -87,9 +88,9 @@
|
||||
<version>5.8.19</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.30</version>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
|
@ -6,7 +6,6 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableSnailJob
|
||||
@ -14,9 +13,6 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
public class SnailJobSpringbootApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ReentrantLock reentrantLock = new ReentrantLock();
|
||||
reentrantLock.lock();
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
|
||||
SpringApplication.run(SnailJobSpringbootApplication.class, args);
|
||||
}
|
||||
|
@ -23,16 +23,16 @@ public class SwaggerConfig {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("Snail Job Example")
|
||||
.description("<h1>SnailJob是致力提高分布式业务系统一致性的分布式重试平台</h1> \n" +
|
||||
"<h3>官网地址: https://www.easyretry.com/</h3>" +
|
||||
"<h3>在线体验地址: http://preview.easyretry.com/</h3> " +
|
||||
"<h3>源码地址: https://gitee.com/byteblogs168/easy-retry-demo</h3>" +
|
||||
.description("<h1>SnailJob是一个灵活,可靠和快速的分布式任务重试和分布式任务调度平台</h1> \n" +
|
||||
"<h3>官网地址: https://snailjob.opensnail.com/</h3>" +
|
||||
"<h3>在线体验地址: https://preview.snailjob.opensnail.com/</h3> " +
|
||||
"<h3>源码地址: https://gitee.com/opensnail/snail-job-demo</h3>" +
|
||||
"<h3>特别提醒: 🌻在您使用测试案例之前请认真的阅读官网.</h3>")
|
||||
.version(SnailJobVersion.getVersion())
|
||||
.license(new License().name("Apache 2.0").url("https://www.easyretry.com/")))
|
||||
.license(new License().name("Apache 2.0").url("https://snailjob.opensnail.com/")))
|
||||
.externalDocs(new ExternalDocumentation()
|
||||
.description("视频教程:从0到1快速了解分布式重试组件EasyRetry")
|
||||
.url("https://www.ixigua.com/pseries/7272009348824433213/"))
|
||||
.description("视频教程:以小白视角的SnailJob入门级视频教程")
|
||||
.url("https://www.bilibili.com/video/BV1pvtBerEmV/?vd_source=ec323e2347232ea82321f54aba036b63"))
|
||||
;
|
||||
}
|
||||
|
||||
|
130
src/main/java/com/example/snailjob/controller/JobController.java
Normal file
130
src/main/java/com/example/snailjob/controller/JobController.java
Normal file
@ -0,0 +1,130 @@
|
||||
package com.example.snailjob.controller;
|
||||
|
||||
import com.aizuda.snailjob.client.job.core.dto.JobResponseVO;
|
||||
import com.example.snailjob.handler.*;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author opensnail
|
||||
* @date 2024-10-19 10:41:25
|
||||
* @since sj_1.2.0-beta2
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/open-api/job")
|
||||
@Tag(name = "JobOpenApi", description = "通过OpenApi可以灵活的实现对Job的增、改、查功能")
|
||||
@RequiredArgsConstructor
|
||||
public class JobController {
|
||||
private final TestAddJobHandler testAddJobHandler;
|
||||
private final TestUpdateJobHandler testUpdateJobHandler;
|
||||
private final TestQueryJobHandler testQueryJobHandler;
|
||||
private final TestTriggerJobHandler testTriggerJobHandler;
|
||||
private final TestUpdateJobStatusHandler testUpdateJobStatusHandler;
|
||||
|
||||
@Operation(
|
||||
description = "添加集群模式的定时任务"
|
||||
)
|
||||
@PostMapping("/custer/add")
|
||||
public Long addClusterJob(@RequestBody String jobName) {
|
||||
return testAddJobHandler.addClusterJob(jobName);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "添加广播模式的定时任务"
|
||||
)
|
||||
@PostMapping("/broadcast/add")
|
||||
public Long addBroadcastJob(@RequestBody String jobName) {
|
||||
return testAddJobHandler.addBroadcastJob(jobName);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "添加静态分片模式的定时任务"
|
||||
)
|
||||
@PostMapping("/sharding/add")
|
||||
public Long addShardingJob(@RequestBody String jobName) {
|
||||
return testAddJobHandler.addShardingJob(jobName);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "添加Map模式的定时任务"
|
||||
)
|
||||
@PostMapping("/map/add")
|
||||
public Long addMapJob(@RequestBody String jobName) {
|
||||
return testAddJobHandler.addMapJob(jobName);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "添加MapReduce模式的定时任务"
|
||||
)
|
||||
@PostMapping("/map-reduce/add")
|
||||
public Long addMapReduceJob(@RequestBody String jobName) {
|
||||
return testAddJobHandler.addMapReduceJob(jobName);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "更新集群模式的定时任务"
|
||||
)
|
||||
@PutMapping("/custer/update")
|
||||
public Boolean updateClusterJob(@RequestBody Long id) {
|
||||
return testUpdateJobHandler.updateClusterJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "更新广播模式的定时任务"
|
||||
)
|
||||
@PutMapping("/broadcast/update")
|
||||
public Boolean updateBroadcastJob(@RequestBody Long id) {
|
||||
return testUpdateJobHandler.updateBroadcastJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "更新静态分片模式的定时任务"
|
||||
)
|
||||
@PutMapping("/sharding/update")
|
||||
public Boolean addShardingJob(@RequestBody Long id) {
|
||||
return testUpdateJobHandler.updateShardingJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "更新Map模式的定时任务"
|
||||
)
|
||||
@PutMapping("/map/update")
|
||||
public Boolean updateMapJob(@RequestBody Long id) {
|
||||
return testUpdateJobHandler.updateMapJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "更新MapReduce模式的定时任务"
|
||||
)
|
||||
@PutMapping("/map-reduce/update")
|
||||
public Boolean updateMapReduceJob(@RequestBody Long id) {
|
||||
return testUpdateJobHandler.updateMapReduceJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "通过任务id查询任务的详情"
|
||||
)
|
||||
@GetMapping("/detail/{id}")
|
||||
public JobResponseVO addMapReduceJob(@PathVariable("id") Long id) {
|
||||
return testQueryJobHandler.queryJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "手动触发任务"
|
||||
)
|
||||
@PostMapping("/trigger/{id}")
|
||||
public Boolean triggerJob(@PathVariable("id") Long id) {
|
||||
return testTriggerJobHandler.triggerJob(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "根据id更新任务的状态",
|
||||
summary = "0:关闭 1:开启"
|
||||
)
|
||||
@PutMapping("/update/status/{id}/{status}")
|
||||
public Boolean updateJob(@PathVariable("id") Long id, @PathVariable("status") Long status) {
|
||||
return testUpdateJobStatusHandler.updateJobStatus(id, status);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.example.snailjob.controller;
|
||||
|
||||
import com.example.snailjob.handler.TestTriggerJobHandler;
|
||||
import com.example.snailjob.handler.TestUpdateJobStatusHandler;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author opensnail
|
||||
* @date 2024-10-19 10:41:25
|
||||
* @since sj_1.2.0-beta2
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/open-api/workflow")
|
||||
@Tag(name = "JobOpenApi", description = "通过OpenApi可以灵活的实现对的Workflow触发和更新状态功能")
|
||||
@RequiredArgsConstructor
|
||||
public class WorkflowController {
|
||||
private final TestTriggerJobHandler testTriggerJobHandler;
|
||||
private final TestUpdateJobStatusHandler testUpdateJobStatusHandler;
|
||||
|
||||
@Operation(
|
||||
description = "手动触发任务"
|
||||
)
|
||||
@PostMapping("/trigger/{id}")
|
||||
public Boolean triggerJob(@PathVariable("id") Long id) {
|
||||
return testTriggerJobHandler.triggerWorkFlow(id);
|
||||
}
|
||||
|
||||
@Operation(
|
||||
description = "根据id更新任务的状态",
|
||||
summary = "0:关闭 1:开启"
|
||||
)
|
||||
@PutMapping("/update/status/{id}/{status}")
|
||||
public Boolean updateJob(@PathVariable("id") Long id, @PathVariable("status") Long status) {
|
||||
return testUpdateJobStatusHandler.updateWorkFlowStatus(id, status);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.example.snailjob.customized;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.aizuda.snailjob.client.core.callback.RetryCompleteCallback;
|
||||
import com.aizuda.snailjob.client.core.callback.complete.RetryCompleteCallback;
|
||||
import com.aizuda.snailjob.common.core.util.JsonUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.example.snailjob.dao.FailOrderBaseMapper;
|
||||
|
@ -45,13 +45,13 @@ public class OnlyRemoteRetryHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Retryable(scene = "localRetryWithRequires", retryStrategy = RetryType.ONLY_LOCAL)
|
||||
@Retryable(scene = "localRetryWithRequires", retryStrategy = RetryType.ONLY_REMOTE)
|
||||
public void localRetryWithRequires(String params) {
|
||||
System.out.println("local retry 方法开始执行");
|
||||
double i = 1 / 0;
|
||||
}
|
||||
|
||||
@Retryable(scene = "localRetryWithRequiresNew", retryStrategy = RetryType.ONLY_LOCAL, propagation = Propagation.REQUIRES_NEW)
|
||||
@Retryable(scene = "localRetryWithRequiresNew", retryStrategy = RetryType.ONLY_REMOTE, propagation = Propagation.REQUIRES_NEW)
|
||||
public void localRetryWithRequiresNew(String params) {
|
||||
System.out.println("local retry 方法开始执行");
|
||||
double i = 1 / 0;
|
||||
|
@ -0,0 +1,126 @@
|
||||
package com.example.snailjob.handler;
|
||||
|
||||
import com.aizuda.snailjob.client.job.core.enums.AllocationAlgorithmEnum;
|
||||
import com.aizuda.snailjob.client.job.core.enums.TriggerTypeEnum;
|
||||
import com.aizuda.snailjob.client.job.core.openapi.SnailJobOpenApi;
|
||||
import com.aizuda.snailjob.common.core.enums.JobBlockStrategyEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TestAddJobHandler {
|
||||
|
||||
/**
|
||||
* 新增集群模式的任务
|
||||
*
|
||||
* @param jobName 任务名称
|
||||
* @return 任务id
|
||||
*/
|
||||
public Long addClusterJob(String jobName) {
|
||||
return SnailJobOpenApi.addClusterJob()
|
||||
.setRouteKey(AllocationAlgorithmEnum.RANDOM)
|
||||
.setJobName(jobName)
|
||||
.setExecutorInfo("testJobExecutor")
|
||||
.setExecutorTimeout(30)
|
||||
.setDescription("add")
|
||||
.setBlockStrategy(JobBlockStrategyEnum.DISCARD)
|
||||
.setMaxRetryTimes(1)
|
||||
.setTriggerType(TriggerTypeEnum.SCHEDULED_TIME)
|
||||
.setTriggerInterval(String.valueOf(60))
|
||||
.addArgsStr("测试数据", 123)
|
||||
.addArgsStr("addArg", "args")
|
||||
.setRetryInterval(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增集群模式的任务
|
||||
*
|
||||
* @param jobName 任务名称
|
||||
* @return 任务id
|
||||
*/
|
||||
public Long addBroadcastJob(String jobName) {
|
||||
return SnailJobOpenApi.addBroadcastJob()
|
||||
.setJobName(jobName)
|
||||
.setExecutorInfo("testJobExecutor")
|
||||
.setExecutorTimeout(30)
|
||||
.setDescription("add")
|
||||
.setBlockStrategy(JobBlockStrategyEnum.DISCARD)
|
||||
.setMaxRetryTimes(1)
|
||||
.setTriggerType(TriggerTypeEnum.CRON)
|
||||
.setTriggerInterval("afas")
|
||||
.addArgsStr("测试数据", 123)
|
||||
.addArgsStr("addArg", "args")
|
||||
.setRetryInterval(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增Sharding模式的任务
|
||||
*
|
||||
* @param jobName 任务名称
|
||||
* @return 任务id
|
||||
*/
|
||||
public Long addShardingJob(String jobName) {
|
||||
return SnailJobOpenApi.addShardingJob()
|
||||
.setJobName(jobName)
|
||||
.setExecutorInfo("testJobExecutor")
|
||||
.setExecutorTimeout(30)
|
||||
.setDescription("add")
|
||||
.setBlockStrategy(JobBlockStrategyEnum.DISCARD)
|
||||
.setMaxRetryTimes(1)
|
||||
.setTriggerType(TriggerTypeEnum.SCHEDULED_TIME)
|
||||
.setTriggerInterval(60)
|
||||
.addShardingArgs("分片1", "分片2", "分片3")
|
||||
.setParallelNum(1)
|
||||
.setRetryInterval(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增MapReduce模式的任务
|
||||
*
|
||||
* @param jobName 任务名称
|
||||
* @return 任务id
|
||||
*/
|
||||
public Long addMapJob(String jobName) {
|
||||
return SnailJobOpenApi.addMapJob()
|
||||
.setJobName(jobName)
|
||||
.setExecutorInfo("testJobExecutor")
|
||||
.setExecutorTimeout(30)
|
||||
.setDescription("add")
|
||||
.setBlockStrategy(JobBlockStrategyEnum.DISCARD)
|
||||
.setMaxRetryTimes(1)
|
||||
.setTriggerType(TriggerTypeEnum.SCHEDULED_TIME)
|
||||
.setTriggerInterval(String.valueOf(60))
|
||||
.setParallelNum(3)
|
||||
.setRetryInterval(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增MapReduce模式的任务
|
||||
*
|
||||
* @param jobName 任务名称
|
||||
* @return 任务id
|
||||
*/
|
||||
public Long addMapReduceJob(String jobName) {
|
||||
return SnailJobOpenApi.addMapReduceJob()
|
||||
.setJobName(jobName)
|
||||
.setExecutorInfo("testJobExecutor")
|
||||
.setExecutorTimeout(30)
|
||||
.setDescription("add")
|
||||
.setBlockStrategy(JobBlockStrategyEnum.DISCARD)
|
||||
.setMaxRetryTimes(1)
|
||||
.setTriggerType(TriggerTypeEnum.SCHEDULED_TIME)
|
||||
.setTriggerInterval(String.valueOf(60))
|
||||
.setParallelNum(3)
|
||||
.setShardNum(2)
|
||||
.setRetryInterval(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.example.snailjob.handler;
|
||||
|
||||
import com.aizuda.snailjob.client.job.core.dto.JobResponseVO;
|
||||
import com.aizuda.snailjob.client.job.core.openapi.SnailJobOpenApi;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TestQueryJobHandler {
|
||||
|
||||
/**
|
||||
* 查看任务详情
|
||||
*
|
||||
* @param jobId
|
||||
* @return 任务详情
|
||||
*/
|
||||
public JobResponseVO queryJob(Long jobId){
|
||||
return SnailJobOpenApi.getJobDetail(jobId).execute();
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.example.snailjob.handler;
|
||||
|
||||
import com.aizuda.snailjob.client.job.core.openapi.SnailJobOpenApi;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TestTriggerJobHandler {
|
||||
|
||||
/**
|
||||
* 手动调度任务
|
||||
*
|
||||
* @param jobId 任务ID
|
||||
* @return
|
||||
*/
|
||||
public Boolean triggerJob(Long jobId) {
|
||||
return SnailJobOpenApi.triggerClusterJob(jobId).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动调度工作流任务
|
||||
*
|
||||
* @param workFlowId 工作流任务ID
|
||||
* @return
|
||||
*/
|
||||
public Boolean triggerWorkFlow(Long workFlowId){
|
||||
return SnailJobOpenApi.triggerWorkFlow(workFlowId).execute();
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.example.snailjob.handler;
|
||||
|
||||
import com.aizuda.snailjob.client.job.core.enums.TriggerTypeEnum;
|
||||
import com.aizuda.snailjob.client.job.core.openapi.SnailJobOpenApi;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Component
|
||||
public class TestUpdateJobHandler {
|
||||
|
||||
/**
|
||||
* 新增集群模式的任务
|
||||
*
|
||||
* @return 任务id
|
||||
*/
|
||||
public Boolean updateClusterJob(Long jobId) {
|
||||
return SnailJobOpenApi.updateClusterJob(jobId)
|
||||
.setMaxRetryTimes(1)
|
||||
.setTriggerType(TriggerTypeEnum.SCHEDULED_TIME)
|
||||
.setTriggerInterval(String.valueOf(60))
|
||||
.addArgsStr("update测试数据", new Random().nextInt(1000))
|
||||
.addArgsStr("updateArg", "args")
|
||||
.setRetryInterval(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增集群模式的任务
|
||||
*
|
||||
* @return 任务id
|
||||
*/
|
||||
public Boolean updateBroadcastJob(Long jobId) {
|
||||
return SnailJobOpenApi.updateBroadcastJob(jobId)
|
||||
.addArgsStr("update测试数据", new Random().nextInt(1000))
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增Sharding模式的任务
|
||||
*
|
||||
* @return 任务id
|
||||
*/
|
||||
public Boolean updateShardingJob(Long jobId) {
|
||||
return SnailJobOpenApi.updateShardingJob(jobId)
|
||||
.addShardingArgs("update分片1", "update分片2", "update分片3")
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增MapReduce模式的任务
|
||||
*
|
||||
* @return 任务id
|
||||
*/
|
||||
public Boolean updateMapJob(Long jobId) {
|
||||
return SnailJobOpenApi.updateMapJob(jobId)
|
||||
.addArgsStr("update测试数据", new Random().nextInt(1000))
|
||||
.setParallelNum(3)
|
||||
.execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增MapReduce模式的任务
|
||||
*
|
||||
* @return 任务id
|
||||
*/
|
||||
public Boolean updateMapReduceJob(Long jobId) {
|
||||
return SnailJobOpenApi.updateMapReduceJob(jobId)
|
||||
.addArgsStr("update测试数据", new Random().nextInt(1000))
|
||||
.execute();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.example.snailjob.handler;
|
||||
|
||||
import com.aizuda.snailjob.client.job.core.openapi.SnailJobOpenApi;
|
||||
import com.aizuda.snailjob.common.core.enums.StatusEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TestUpdateJobStatusHandler {
|
||||
|
||||
/**
|
||||
* 更新定时任务状态
|
||||
*
|
||||
* @param jobId 定时任务ID
|
||||
* @return
|
||||
*/
|
||||
public Boolean updateJobStatus(Long jobId, Long status) {
|
||||
return SnailJobOpenApi
|
||||
.updateJobStatus(jobId)
|
||||
.setStatus(StatusEnum.YES.getStatus().equals(status.intValue()) ? StatusEnum.YES : StatusEnum.NO)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新工作流任务状态
|
||||
*
|
||||
* @param workFlowId 工作流ID
|
||||
* @param status
|
||||
* @return
|
||||
*/
|
||||
public Boolean updateWorkFlowStatus(Long workFlowId, Long status) {
|
||||
return SnailJobOpenApi
|
||||
.updateWorkFlowStatus(workFlowId)
|
||||
.setStatus(StatusEnum.YES.getStatus().equals(status.intValue()) ? StatusEnum.YES : StatusEnum.NO)
|
||||
.execute();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.example.snailjob.job;
|
||||
|
||||
import com.aizuda.snailjob.client.common.log.report.LogMeta;
|
||||
import com.aizuda.snailjob.client.common.log.support.SnailJobLogManager;
|
||||
import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
|
||||
import com.aizuda.snailjob.client.job.core.dto.JobArgs;
|
||||
import com.aizuda.snailjob.client.job.core.executor.JobContextManager;
|
||||
import com.aizuda.snailjob.client.model.ExecuteResult;
|
||||
import com.aizuda.snailjob.common.core.model.JobContext;
|
||||
import com.aizuda.snailjob.common.log.SnailJobLog;
|
||||
import com.aizuda.snailjob.common.log.enums.LogTypeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author PT
|
||||
* @date 2024-09-02 上午10:50
|
||||
* @Description
|
||||
* 线程异步情况下日志打印,场景:定时调用接口更新数据,
|
||||
* 由于数据量每天大小不一致,无法界定执行时间,所以需要异步执行,但是异步执行时日志也需要进行打印
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TestSyncLogPrintExecutor {
|
||||
|
||||
@JobExecutor(name = "TestSyncLogPrintExecutor")
|
||||
public ExecuteResult jobExecute(JobArgs jobArgs) {
|
||||
JobContext jobContext = JobContextManager.getJobContext();
|
||||
LogMeta logMeta = SnailJobLogManager.getLogMeta();
|
||||
LogTypeEnum logType = SnailJobLogManager.getLogType();
|
||||
|
||||
//此处简单模拟开启新线程执行,实际生产建议使用线程池执行
|
||||
new Thread(() -> {
|
||||
JobContextManager.setJobContext(jobContext);
|
||||
SnailJobLogManager.setLogMeta(logMeta);
|
||||
SnailJobLogManager.setLogType(logType);
|
||||
//执行业务
|
||||
doSomething();
|
||||
});
|
||||
return ExecuteResult.success();
|
||||
}
|
||||
|
||||
private void doSomething() {
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(10);
|
||||
SnailJobLog.REMOTE.info("测试异步打印");
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ snail-job:
|
||||
# 服务器IP地址(或域名);集群时建议通过 nginx 做负载均衡
|
||||
host: 127.0.0.1
|
||||
# 服务器通讯端口(不是后台管理页面服务端口)
|
||||
port: 1788
|
||||
port: 17888
|
||||
# 命名空间
|
||||
namespace: 764d604ec6fc45f68cd92514c40e9e1a
|
||||
# 接入组名
|
||||
@ -56,4 +56,5 @@ snail-job:
|
||||
# 客户端绑定IP,必须服务器可以访问到;默认自动推断,在服务器无法调度客户端时需要手动配置
|
||||
host: 127.0.0.1
|
||||
# 客户端通讯端口,默认 1789
|
||||
port: 1789
|
||||
port: 17889
|
||||
rpc-type: grpc
|
||||
|
Loading…
Reference in New Issue
Block a user