Spring和后台线程执行

时间:2017-01-31 12:33:27

标签: java spring multithreading

我有一个Spring Boot 1.3.5 Web应用程序(在Tomcat 8上运行),它的一个功能是通过REST联系第三方API并启动许多lenghty作业(从1到大约30个,具体取决于用户输入,每个都在for循环中有自己的REST调用)。我在控制器中使用所有这些逻辑,使用带有一些参数的POST。

我需要的是在API确认每个作业后启动后台任务,这将通过一些参数(作业ID)并定期(~30秒)轮询另一个API以获取作业输出(同样,这些工作可能需要几秒到一个小时,并且其工作大约需要3-4秒,再加上解析长字符串)并根据其状态执行一些业务逻辑(暂时更新数据库记录)

但是我不确定要使用哪个TaskExecutor,或者我是否应该使用Java的Future结构。我可能会从一个线程池中受益,该线程池只会并行运行X线程并将其他线程排队以使服务器不会过载。有一个例子我可以学习并开始学习吗?

我现有代码的示例:

@RequestMapping(value={"/job/launch"}, method={RequestMethod.POST})
public ResponseEntity<String> runJob(HttpServletRequest req) {
    for (int deployments=1; deployments <= deployments_required; deployments++) {
        httpPost.setEntity((HttpEntity)new StringEntity(jsonInput));
        CloseableHttpResponse response = httpclient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        responseString = EntityUtils.toString(entity, "UTF-8");
        JsonObject jsonObject = new JsonParser().parse(responseString).getAsJsonObject();
        if (response.getStatusLine().getStatusCode() != 200) {
            resultsNotOk.add(new ResponseEntity<String>(jsonObject.get("message").getAsString(), HttpStatus.INTERNAL_SERVER_ERROR));
            continue;
        }
        String deploymentId;
        deploymentId = jsonObject.get("id").getAsString();
        // Start background task to keep checking the job every few seconds and find created instance IP addresses
        start_checking_execution(deploymentId);
    }
}

(是的,这个代码可能最好放在一个服务中,但它最初是按原样构建的,所以我还没有移动它。现在可能是现在这样做的好时机)

1 个答案:

答案 0 :(得分:0)

我会说Spring Batch

的工作

您可以定义Reader / Processor(将源读取转换为目标写入对象)/ Writer以使用逻辑

您可以使用JobOperator获取作业状态。见job status transitions