java异步编排工具-asyncTool

一、介绍

一款开源工具AsyncTool:

https://gitee.com/jd-platform-opensource/asyncTool

是由京东零售的高级工程师编写的,提供了非常丰富的异步编排功能,并且经过了京东内部的测试,是对CompletableFuture的封装和补足

二、引入

1)、不推荐:maven引入,这个比较坑,客观原因经常会导致依赖下载不下来,不推荐使用;

2)、推荐:直接下载源码,因为代码量很少,就几个核心类和测试类。
如下图所示,把下载的源码拷贝进来即可,核心代码放到java目录里面,测试代码放到test目录里面。
image
编写案例:

  • 编写worker
    构建worker十分简单,只需要实现IWorker和ICallback接口即可,其中begin方法是构建开始时会执行,result方法是获取到结果后会执行,action方法就是处理具体任务的地方,一般业务就在这里编写,defaultValue方法提供超时异常时返回的默认值。
package com.example.work.demo;

import com.jd.platform.async.worker.WorkResult;
import com.jd.platform.async.wrapper.WorkerWrapper;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description :
 * @Date : 2024/2/23
 * @Author :
 */
public class Test1 implements com.jd.platform.async.callback.IWorker<String,String> , com.jd.platform.async.callback.ICallback<String,String> {

    @Override
    public void result(boolean success, String param, WorkResult<String> workResult) {
        System.out.println("test1的callback"+workResult.getResult());
    }

    @Override
    public String action(String str, Map<String, WorkerWrapper> allWrappers) {
        System.out.println("Test1入参"+str);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (Exception e) {

        }
        return "test1--";
    }
}
package com.example.work.demo;

import com.jd.platform.async.worker.WorkResult;
import com.jd.platform.async.wrapper.WorkerWrapper;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description :
 * @Date : 2024/2/23
 * @Author :
 */
public class Test2 implements com.jd.platform.async.callback.IWorker<String, String>, com.jd.platform.async.callback.ICallback<String, String> {
    @Override
    public void result(boolean success, String param, WorkResult<String> workResult) {
        System.out.println("test2call" + workResult.getResult());
    }

    @Override
    public String action(String object, Map<String, WorkerWrapper> allWrappers) {
        System.out.println("test2入参" + object);
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (Exception e) {

        }
        return "test2---";
    }
}
package com.example.work.demo;

import com.jd.platform.async.worker.WorkResult;
import com.jd.platform.async.wrapper.WorkerWrapper;

import java.util.Map;

/**
 * @Description :
 * @Date : 2024/2/23
 * @Author :
 */
public class Test3 implements com.jd.platform.async.callback.IWorker<String,Integer>, com.jd.platform.async.callback.ICallback<String,Integer> {

    @Override
    public void result(boolean success, String param, WorkResult<Integer> workResult) {
        System.out.println("test3callbak"+workResult.getResult());
    }

    @Override
    public Integer action(String object, Map<String, WorkerWrapper> allWrappers) {
        System.out.println("test3参数"+object);

        System.out.println("从test1传来的参数"+allWrappers.get("first").getWorkResult().getResult());
        System.out.println("从test2传来的参数"+allWrappers.get("second").getWorkResult().getResult());
        return 1;
    }
}
  • 异步编排
    新建一个AsyncToolService,在里面进行worker的声明、构建、编排;Async.beginWork就是执行异步任务,参数分别为超时时间和worker,其中超时时间可以自己设短一点看效果;
package com.example.work.demo;

import java.util.concurrent.ExecutionException;

/**
 * @Description :
 * @Date : 2024/2/23
 * @Author :
 */
public class Tt {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Test1 test1 = new Test1();
        Test2 test2 = new Test2();
        Test3 test3 = new Test3();

        com.jd.platform.async.wrapper.WorkerWrapper<String, Integer> workerWrapper3 =  new com.jd.platform.async.wrapper.WorkerWrapper.Builder<String, Integer>()
                .worker(test3)
                .callback(test3)
                .id("third")
                .param("----3")
                .build();
        com.jd.platform.async.wrapper.WorkerWrapper<String, String> workerWrapper2 =  new com.jd.platform.async.wrapper.WorkerWrapper.Builder<String, String>()
                .worker(test2)
                .callback(test2)
                .id("second")
                .param("----2")
                .next(workerWrapper3)
                .build();
        com.jd.platform.async.wrapper.WorkerWrapper<String, String> workerWrapper1 =  new com.jd.platform.async.wrapper.WorkerWrapper.Builder<String, String>()
                .worker(test1)
                .callback(test1)
                .id("first")
                .param("----1")
                .next(workerWrapper3)
                .build();


        com.jd.platform.async.executor.Async.beginWork(10000, workerWrapper1, workerWrapper2,workerWrapper3);

    }
}

输出
image
AsyncTool的QuickStart.md已经做了简洁的说明:https://gitee.com/jd-platform-opensource/asyncTool/blob/master/QuickStart.md

3、demo介绍

  • 任务并行
    image
  • 串行加并行
    image
  • 依赖其他结果
    这也是很常见的场景,B任务依赖A任务的结果来实现业务,最后返回。
    AsyncTool也提供了很方便的方式:
    1)、在service中构建worker-A时设置一个id名称;
    2)、你可以发现worker的action方法第二个入参是个map,里面就是所有的wrapper;
    3)、在worker-B的action方法中get这个id来获取wrapper从而拿到A的结果即可。
    image
    image

4、踩坑

4.1 勿关闭线程池
AsyncTool提供了很多测试类,里面包含了所有编排方式,可以一一查看并验证,但使用过程中要注意一点,如果是spring-web项目,比如springboot,不需要手动Async.shutdown()处理,否则会执行一次后就关闭线程池了,这是不少人直接拷贝test代码疏忽的地方。

image

posted @ 2024-02-26 10:42  spiderMan1-1  阅读(415)  评论(0编辑  收藏  举报