获取执行进度

场景描述

当任务长时间执行时,获取其执行的进度

实现思路

服务如果耗时久,可以设置为异步执行,对于异步执行的服务,有两种方式获取其执行进度:

  • 调度中心定时轮询:即定时调用一个请求,在请求中获取执行进度,执行进度作为请求的返回值,调度中心将这个返回值发送给任务的通知请求模板
  • 在服务中主动调用$(feedbackUrl):此为调度中心的环境变量,将执行进度作为参数传递给调度中心,调度中心将这个参数发送给任务的通知请求模板
  • 在通知请求模板中可以将进度通知给人(通过消息中心发送消息),或通过事件中心触发事件,前端页面通过订阅组件接收事件

实现步骤

1 任务模板

任务中包括请求模板、检查结果模板和通知模板。每个模板中都包括至少一个请求url。这些请求url是如何触发的?分为下面三种情况:

  • 同步任务
    • 调度中心开始一个任务,调用请求模板中的请求url
    • 请求url执行后,调用通知模板中的通知请求url
  • 异步任务(调度中心轮询检查)
    • 调度中心开始一个任务,调用请求模板中的请求url
    • 调度中心根据检查频率,定期调用检查结果模板中的检查请求url
      • 检查请求url返回status("")表示任务执行中
      • 检查请求url返回status("succeed")表示任务执行完成
    • 调度中心将检查请求url的返回结果发给通知模板中的通知请求url
  • 异步任务(任务主动反馈)
    • 调度中心开始一个任务,调用请求模板中的请求url,请求参数中必须包括调度中心的环境变量反馈url:${feedbackUrl}
    • 请求url中,根据进度调用反馈url
      • 调用反馈url的参数中包括status("")表示任务执行中
      • 调用反馈url的参数中包括status("succeed")表示任务执行完成
    • 调度中心将反馈url的参数发给通知模板中的通知请求url

2 调度中心定时轮询

调度中心轮询获取任务执行的进度和状态,调用检查结果请求url,响应数据格式如下:

{
    "status":"failed",  //任务状态: failed表示失败  succeed表示成功  为空表示正在执行
    "message": "执行MySQL...",   // 提示信息
    "error":"error1",   //status为failed时,用户定义的error码,方便在重试策略里使用
    "progress":"30%",   //任务进度,返回形式,20/60 或者 30%
    "data":{}   //返回的业务数据
}

注:当error不为空,status为空时,是非法的

定义一个异步执行的任务,对于一个异步任务来说,必须设置检查模板或主动调用feedbackUrl,本例使用设置检查模板,任务定义如下图所示

  • 请求模板url:service://test/main/fuwu/query2?jobid=${jobId}
  • 检查模板url:service://test/main/fuwu/checkexe?jobid=${jobId}&executeNumber=${executeNumber}

调度中心调用请求模板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
    }
}
]

3 在任务中主动反馈执行信息给调度中心

任务服务按需给调度中心反馈任务执行的进度和状态,反馈请求的url为环境变量${feedbackUrl},调度中心请求url时作为参数传入。反馈请求为POST请求,请求体数据格式如下:

{
    "status":"failed",  //任务状态: failed表示失败  succeed表示成功  为空表示正在执行
    "message": "执行MySQL...",   // 提示信息
    "error":"error1",   //status为failed时,用户定义的error码,方便在重试策略里使用
    "progress":"30%",   //任务进度,返回形式,20/60 或者 30%,
    "data":{}   //返回的业务数据
}

注:当error不为空,status为空时,是非法的

定义一个异步执行的任务,对于一个异步任务来说,必须设置检查模板或主动调用feedbackUrl,本例主动调用feedbackUrl,任务定义如下图所示

  • 请求模板url:service://test/main/fuwu/query3?callback=${feedbackUrl}

调度中心调用请求模板url开始一个异步任务,请求启动一个线程用来处理任务,并调用feedbackUrl反馈调度中心。请求本身需要在超时时间内执行完成,否则调度中心会认为请求超时。在线程中调用反馈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("feedbackUrl-->" + 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
    }
}
]

4 设置环境变量

如果输出的反馈url不是以http开头,而是以域名开头,则需要设置环境变量,重新给出以http开头的url

用租户管理员登录控制台,打开应用服务管理,点击任务调度应用右侧的配置按钮

点击环境变量右侧的设置按钮

点击comp.jobs右侧的设置参数按钮

取出反馈url前面的域名,在前面加上http://,填入下图的输入框

确定后,重启任务调用应用,输出的反馈url就会以http开头了。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""