多种方式创建 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 组件

Alt text

添加 jobs-client 依赖

    <dependency>
      <groupId>com.justep.cloud</groupId>
      <artifactId>jobs-client</artifactId>
      <version>1.0.0</version>
    </dependency>

Alt text

Alt text

添加服务写 java 代码

核心工具类 com.justep.cloud.job.client.JobsClientApi

核心是组装 jobInfo

  1. 构造调度策略 TimerTemplate
  2. 构造 checkUrl CheckUrlTemplate
  3. 构造重试策略 RetryTemplate
  4. 构造notifier通知 NotifierTemplate
  5. 构造请求模板 RequestTemplate
  6. 构造 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 添加“定时和事件设置”组件

Alt text

进入配置界面进行配置

Alt text

Alt text

配置保存后 timer 存在 UI2\pcx\timerAndTrigger.serviceMetaInfo.json 文件中,如果需要更细节定义,可在此文件中直接进行编码,定义规则请参考《技术架构、接口和运行原理》的“创建任务”

Alt text

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 资源进行导出备份。

Alt text

results matching ""

    No results matching ""