多种方式创建 job 作业
通过接口调用
参考《技术架构、接口和运行原理》中“服务接口”——》“创建任务”,主要使用场景用于测试,进入任务调度的 java-runtime 容器执行 curl 命令创建
curl -X POST 'http://127.0.0.1/jobs/CAC447233AB00001BDBF181DBB001CF4' \
-H 'Accept: */*' \
-H 'content-type: application/json' \
-d '{"jobId":"CAC447233AB00001BDBF181DBB001CF4","jobName":"job测试checkURL 测试","jobDescription":"走起...","creator":"001","creatorName":"service-client","notification":[{"headers":{"hello":"system"},"method":"POST","body":"${schedulingNotifyBody}|json","url":"service://jobsclient/main/notifierClient/${schedulingJobId}?executeNumber=${schedulingExecuteNumber}"}],"timer":{"period":"0 0/1 * * * ?","dueTime":"2s","ttl":"5d3s"},"request":[{"headers":{"hello":"system"},"method":"POST","responseHeader":false,"formCommit":false,"body":{"classSize":2,"teacher":"陈同学","student":[{"number":1,"name":"${schedulingJobId}","age":40},{"number":8,"name":"${schedulingJobId}","age":30}],"describe":"云师大附中..."},"url":"service://jobswork/main/resultHandleSchool"},{"headers":{"hello":"system"},"method":"POST","responseHeader":false,"formCommit":false,"body":{"school":"${$.student}|json"},"url":"service://jobswork/main/workHandleStr"}],"async":1,"checkUrl":{"headers":{"hello":"system"},"method":"GET","url":"service://jobswork/main/provideCheckUrl/${schedulingJobId}?executeNumber=${schedulingExecuteNumber}"},"checkRateSeconds":4,"timeoutSeconds":15,"retry":[{"maxAttempts":2,"backoffRate":1.5,"errorEquals":"500","intervalSeconds":2},{"maxAttempts":2,"backoffRate":2,"errorEquals":"timeout","intervalSeconds":5},{"maxAttempts":2,"backoffRate":2,"errorEquals":"error1","intervalSeconds":3}],"qos":0,"parentJob":null,"parentJobExecution":null}'
通过 java SDK
通过 java SDK 创建 job,主要使用场景固定模式的业务开发
添加 jobsClient 依赖
添加 jobsClient 组件
添加 jobs-client 依赖
<dependency>
<groupId>com.justep.cloud</groupId>
<artifactId>jobs-client</artifactId>
<version>1.0.0</version>
</dependency>
或
添加服务写 java 代码
核心工具类 com.justep.cloud.job.client.JobsClientApi
核心是组装 jobInfo
- 构造调度策略 TimerTemplate
- 构造 checkUrl CheckUrlTemplate
- 构造重试策略 RetryTemplate
- 构造notifier通知 NotifierTemplate
- 构造请求模板 RequestTemplate
- 构造 jobInfo
/**
* jobs、jobswork、jobsclient
*/
@Service
public class JobclientUserServiceImpl implements JobclientService {
public static Logger log = Logger.getLogger(JobclientUserServiceImpl.class);
private static final String JOBID = "20220125";
private static final String jobServiceName = "scheduling";
private static final String jobServiceUrl = ServiceUtil.getServiceUrl("scheduling");
private JobInfo packageJobInfo(){
// 调度策略
TimerTemplate timer = TimerTemplate.builder().dueTime("2s").period("30s").build();
TimerTemplate timer1 = TimerTemplate.builder().dueTime("2s").period("0 0/1 * * * ?").build();
// ide调试的头
Map<String, String> extHeaders = ServiceUtil.getExtHeaders(SpringWebUtil.getRequest());
Map<String, Object> headers = new HashedMap<String, Object>();
headers.putAll(extHeaders); // 如果要进行ide之间的调式需将extHeaders携带
headers.put("name","chensc");
// checkURL,用于作业状态检查,目标作业服务
CheckUrlTemplate checkUrl = CheckUrlTemplate.builder()
.url("service://jobswork/main/provideCheckUrl/${schedulingJobId}?executeNumber=${schedulingExecuteNumber}")
.headers(headers)
.method("GET")
.build();
// 重试策略
List<RetryTemplate> retrys = new ArrayList<>();
RetryTemplate retryTemplate = RetryTemplate.builder()
.errorEquals("500")
.intervalSeconds(2)
.maxAttempts(2)
.backoffRate(1.5f)
.build();
retrys.add(retryTemplate);
RetryTemplate retryTemplate1 = RetryTemplate.builder()
.errorEquals("timeout")
.intervalSeconds(5)
.maxAttempts(2)
.backoffRate(2f)
.build();
retrys.add(retryTemplate1);
RetryTemplate retryTemplate2 = RetryTemplate.builder()
.errorEquals("error1")
.intervalSeconds(3)
.maxAttempts(2)
.backoffRate(2f)
.build();
retrys.add(retryTemplate2);
// Notify,作业状态通知,目标源头调用服务
List<NotifierTemplate> notifiers = new ArrayList<>();
NotifierTemplate notifierTemplate = NotifierTemplate.builder()
.method("POST")
.stateEquals("finalSucceed")
.headers(headers)
.body("${schedulingNotifyBody}|json")
.url("service://jobsclient/main/notifierClient/${schedulingJobId}?executeNumber=${schedulingExecuteNumber}")
.build();
NotifierTemplate notifierTemplate1 = NotifierTemplate.builder()
.method("POST")
.headers(headers)
.body("${schedulingNotifyBody}|json")
.url("service://jobsclient/main/notifierClient/${schedulingJobId}?executeNumber=${schedulingExecuteNumber}")
.build();
// notifiers.add(notifierTemplate);
notifiers.add(notifierTemplate1);
// request,真正的任务作业
List<RequestTemplate> requests = new ArrayList<>();
List<Student> students = new ArrayList<>();
Student student1 = Student.builder().age(40).name("${schedulingJobId}").number(1).build();
students.add(student1);
Student student2 = Student.builder().age(30).name("${schedulingJobId}").number(8).build();
students.add(student2);
School school = School.builder()
.classSize(2)
.describe("师大附中...")
.teacher("陈同学")
.student(students)
.build();
JSONObject jsonSchool = (JSONObject) JSONObject.toJSON(school);
RequestTemplate requestTemplate1 = RequestTemplate.builder()
.method("POST")
.url("service://jobswork/main/resultHandleSchool")
.headers(headers)
.body(jsonSchool)
.build();
requests.add(requestTemplate1);
Map<String,Object> receiveBody = new HashMap<>();
receiveBody.put("school","${$.student}|json");
JSONObject jsonReceiveBody = (JSONObject) JSONObject.toJSON(receiveBody);
RequestTemplate requestTemplate2 = RequestTemplate.builder()
.method("POST")
.url("service://jobswork/main/workHandleStr")
.headers(headers)
.body(jsonReceiveBody)
.build();
requests.add(requestTemplate2);
JobInfo jobInfo = JobInfo.builder()
.jobId(JOBID)
.jobName("job测试checkURL")
.jobDescription("走起...")
.creator("001")
.creatorName("service-client")
.timer(timer1)
.async(true)
.checkRateSeconds(4)
.checkUrl(checkUrl)
.timeoutSeconds(15)
.qos(0)
.retry(retrys)
.notification(notifiers)
.request(requests)
.createTime(new Date())
.build();
System.out.println(JSON.toJSONString(jobInfo));
return jobInfo;
}
public String createJob() throws Exception {
log.info("createJob==================");
JobInfo jobInfo = packageJobInfo();
log.info("jobServiceUrl-->" + jobServiceUrl);
ControllerResult result = JobsClientApi.createJob(JOBID,jobInfo,jobServiceName);
log.info("packageJobInfo result--》"+JSON.toJSONString(result));
return "createJob成功";
}
}
通过配置 timer 列表
使用场景与 java SDK 一样,只不过简化了复杂的代码编写过程,开发者只需要简单的配置就能够实现 job 创建
打开 ide 添加“定时和事件设置”组件
进入配置界面进行配置
配置保存后 timer 存在 UI2\pcx\timerAndTrigger.serviceMetaInfo.json 文件中,如果需要更细节定义,可在此文件中直接进行编码,定义规则请参考《技术架构、接口和运行原理》的“创建任务”
timer
"timer": [
{
"jobName": "job测试feedback",
"request": [
{
"headers": {
"name": "chensc"
},
"method": "POST",
"body": {
"classSize": 2,
"teacher": "陈奕迅",
"student": [
{
"number": 1,
"name": "${jobId}",
"age": 40
},
{
"number": 8,
"name": "${jobId}",
"age": 30
}
],
"describe": "师大附中..."
},
"url": "service://jobswork/main/resultHandleSchool"
},
{
"headers": {
"name": "chensc"
},
"method": "POST",
"body": {
"school": "${$.student}|json"
},
"url": "service://jobswork/main/workHandleSchool?feedbackUrl=${schedulingFeedbackUrl}"
}
],
"creator": "001",
"creatorName": "jobswork本身",
"active": 1,
"async": true,
"jobId": "123456789",
"notification": [
{
"headers": {
"name": "chensc"
},
"body": "${schedulingNotifyBody}|json",
"method": "POST",
"url": "service://jobsclient/main/notifierClient/${schedulingJobId}?executeNumber=${schedulingExecuteNumber}"
}
],
"timer": {
"period": "0 0/5 * * * ?",
"dueTime": "2s"
},
"qos": 0,
"timeoutSeconds": 60,
"jobDescription": "走起...",
"retry": [
{
"maxAttempts": 2,
"backoffRate": 1.5,
"errorEquals": "500",
"intervalSeconds": 2
},
{
"maxAttempts": 2,
"backoffRate": 2.0,
"errorEquals": "timeout",
"intervalSeconds": 5
},
{
"maxAttempts": 2,
"backoffRate": 2.0,
"errorEquals": "error1",
"intervalSeconds": 3
}
]
}
]
通过任务调度页面
通过任务调度页面创建的 job,平台只认为是一种临时 job,不会对该 job 资源进行备份保护,在极端环境下可能会丢失 job 资源。所以建议开发时多使用 java SDK 创建、或配置 timer 列表的方式进行创建。如果必须使用临时 job,请自行定期对 job 资源进行导出备份。