获取执行进度
当任务长时间执行时,获取其执行的进度。服务如果耗时久,可以设置为异步执行,对于异步执行的服务,有两种方式获取其执行进度:
- 调度中心定时轮询:即定时调用一个请求,在请求中获取执行进度,执行进度作为请求的返回值,调度中心将这个返回值发送给任务的通知请求模板
- 在服务中主动调用 ${schedulingFeedbackUrl}:此为调度中心的环境变量,将执行进度作为参数传递给调度中心,调度中心将这个参数发送给任务的通知请求模板
- 在通知请求模板中可以将进度通知给人(通过消息中心发送消息),或通过事件中心触发事件,前端页面通过订阅组件接收事件
任务模板
任务中包括请求模板、检查结果模板和通知模板。每个模板中都包括至少一个请求 url。这些请求 url 是如何触发的?分为下面三种情况:
- 同步任务
- 调度中心开始一个任务,调用请求模板中的请求 url
- 请求 url 执行后,调用通知模板中的通知请求 url
- 异步任务(调度中心轮询检查)
- 调度中心开始一个任务,调用请求模板中的请求 url
- 调度中心根据检查频率,定期调用检查结果模板中的检查请求 url
- 检查请求 url 返回 status("") 表示任务执行中
- 检查请求 url 返回 status("succeed") 表示任务执行完成
- 调度中心将检查请求 url 的返回结果发给通知模板中的通知请求 url
- 异步任务(任务主动反馈)
- 调度中心开始一个任务,调用请求模板中的请求 url,请求参数中必须包括调度中心的环境变量反馈 url:${schedulingFeedbackUrl}
- 请求 url 中,根据进度调用反馈 url
- 调用反馈 url 的参数中包括 status("") 表示任务执行中
- 调用反馈 url 的参数中包括 status("succeed") 表示任务执行完成
- 调度中心将反馈 url 的参数发给通知模板中的通知请求 url
调度中心定时轮询
调度中心轮询获取任务执行的进度和状态,调用检查结果请求 url,响应数据格式如下:
{
"status":"failed", //任务状态: failed表示失败 succeed表示成功 为空表示正在执行
"message": "执行MySQL...", // 提示信息
"error":"error1", //status为failed时,用户定义的error码,方便在重试策略里使用
"progress":"30%", //任务进度,返回形式,20/60 或者 30%
"data":{} //返回的业务数据
}
注:当 error 不为空,status 为空时,是非法的
定义一个异步执行的任务,对于一个异步任务来说,必须设置检查模板或主动调用 schedulingFeedbackUrl,本例使用设置检查模板,任务定义如下图所示
- 请求模板 url:service://test/main/fuwu/query2?jobId=${schedulingJobId}
- 检查模板 url:service://test/main/fuwu/checkexe?jobId=${schedulingJobId}\&executeNumber=${schedulingExecuteNumber}
调度中心调用请求模板 url 开始一个异步任务,请求本身执行完不代表异步任务执行完,在调用检查模板 url 中返回 status("") 表示任务执行中,返回 status("succeed") 表示异步任务执行完成。代码如下:
//定义全局变量
private int taskProgress = 0;
//任务的请求方法
public String query2(String jobId) throws Exception {
//设置进度
taskProgress = 0;
return "OK2";
}
//任务的检查进度方法
public String checkExe(String jobId,String executeNumber) throws Exception {
//设置进度
taskProgress ++;
String step = "0%";
switch(taskProgress) {
case 0: step = "0%";break;
case 1: step = "33%";break;
case 2: step = "66%";break;
default: step = "100%";
}
if(taskProgress<3){
//返回任务状态为执行中
Results ret = Results.builder().progress(step)
.message("异步服务执行到"+step).status("").build();
return JSON.toJSONString(ret);
}else{
//返回任务状态为执行成功
Results ret = Results.builder().progress(step)
.message("异步服务执行到"+step).status("succeed").build();
return JSON.toJSONString(ret);
}
}
查看任务执行记录中的通知结果集,包括五条通知,其中
- 第一条是调用请求 url 后,调度中心发送的
- 中间三条是调用检查请求 url 后,调度中心发送的
- 最后一条是调度中心判定任务执行成功后发送的
结果显示如下:
[
{
"1": {
"response": {
"data": {
"data": "OK2"
},
"progress": "1%",
"message": "异步调用request成功...",
"status": ""
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "33%",
"message": "异步服务执行到33%",
"status": ""
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "66%",
"message": "异步服务执行到66%",
"status": ""
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "100%",
"message": "异步服务执行到100%",
"status": "succeed"
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "100%",
"message": "异步execute最终成功...",
"status": "finalSucceed"
},
"httpStatus": 200
}
}
]
在任务中主动反馈执行信息给调度中心
任务服务按需给调度中心反馈任务执行的进度和状态,反馈请求的 url 为环境变量 ${schedulingFeedbackUrl},调度中心请求 url 时作为参数传入。反馈请求为 POST 请求,请求体数据格式如下:
{
"status":"failed", //任务状态: failed表示失败 succeed表示成功 为空表示正在执行
"message": "执行MySQL...", // 提示信息
"error":"error1", //status为failed时,用户定义的error码,方便在重试策略里使用
"progress":"30%", //任务进度,返回形式,20/60 或者 30%,
"data":{} //返回的业务数据
}
注:当 error 不为空,status 为空时,是非法的
定义一个异步执行的任务,对于一个异步任务来说,必须设置检查模板或主动调用 schedulingFeedbackUrl,本例主动调用 schedulingFeedbackUrl,任务定义如下图所示
- 请求模板 url:service://test/main/fuwu/query3?callback=${schedulingFeedbackUrl}
调度中心调用请求模板 url 开始一个异步任务,请求启动一个线程用来处理任务,并调用 schedulingFeedbackUrl 反馈调度中心。请求本身需要在超时时间内执行完成,否则调度中心会认为请求超时。在线程中调用反馈 url 时,发送 status("") 表示任务执行中,发送 status("succeed") 表示异步任务执行完成。代码如下:
//定义全局变量
private String callbackUrl= "";
//定义线程
class SomeRunnable implements Runnable {
public void run() {
HashMap<String, String> headerMap = new HashMap<>();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
JSONObject params = new JSONObject();
params.put("status", "");
params.put("message", "zx异步任务3执行到50%");
params.put("progress", "50%");
//调用反馈url
ServiceUtil.post(callbackUrl, params, headerMap);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
JSONObject params2 = new JSONObject();
params2.put("status", "succeed");
params2.put("message", "zx异步任务3执行到100%");
params2.put("progress", "100%");
//调用反馈url
ServiceUtil.post(callbackUrl, params2, headerMap);
}
}
//任务的请求方法
public String query3(String callback) throws Exception {
System.out.println("schedulingFeedbackUrl-->" + callback);
callbackUrl = callback;
//启动线程
Runnable oneRunnable = new SomeRunnable();
Thread oneThread = new Thread(oneRunnable);
oneThread.start();
return "OK3";
}
查看任务执行记录中的通知结果集,包括四条通知,其中
- 第一条是调用请求 url 后,调度中心发送的
- 中间两条是任务服务调用反馈请求 url 后,调度中心发送的
- 最后一条是调度中心判定任务执行成功后发送的
结果显示如下:
[
{
"1": {
"response": {
"data": {
"data": "OK3"
},
"progress": "1%",
"message": "异步调用request成功...",
"status": ""
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "50%",
"message": "zx异步任务3执行到50%",
"status": ""
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "100%",
"message": "zx异步任务3执行到100%",
"status": "succeed"
},
"httpStatus": 200
}
},
{
"1": {
"response": {
"progress": "100%",
"message": "异步execute最终成功...",
"status": "finalSucceed"
},
"httpStatus": 200
}
}
]
设置环境变量
如果输出的反馈 url 不是以 http 开头,而是以域名开头,则需要设置环境变量,重新给出以 http 开头的 url
用租户管理员登录控制台,打开应用服务管理,点击任务调度应用右侧的配置按钮
切换到环境设置标签页,点击 comp.jobs 右侧的设置参数按钮
取出反馈 url 前面的域名,在前面加上 http://
,填入下图的输入框
确定后,重启任务调用应用,输出的反馈 url 就会以 http 开头了。 http://entrydevguide8-vip.trunk2.xcaas.com:8800/scheduling/