目录
  1. 1. 前言
  2. 2. 集成方法
  3. 3. 使用方法
Springboot集成Async异步调用

前言

在业务开发过程中,有时会遇到非核心的业务,如记录日志或发送短信等。有时也会遇到一次性要处理多个任务,再将多个任务处理结果进行返回。如果做同步处理时,会比较耗时,对于接口而言,响应速度慢一方面会影响用户体验,另一方面如果是服务间调用,可能会出现超时的情况。这种情况我们可以采用异步处理的方式,提高主流程的性能。

集成方法

1、springboot启动类添加@EnableAsync注解

1
2
3
4
5
6
7
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

2、创建配置属性类AsyncProperties

1
2
3
4
5
6
7
8
9
@Component
@Data
@ConfigurationProperties(prefix = "async")
public class AsyncProperties {
private int corePoolSize;
private int maxPoolSize;
private int queueCapacity;
private int keepAlive;
}

3、添加异步配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Configuration
@Slf4j
public class AsyncConfig implements AsyncConfigurer {
@Autowired
private AsyncProperties asyncProperties;
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(asyncProperties.getCorePoolSize());
executor.setMaxPoolSize(asyncProperties.getMaxPoolSize());
executor.setQueueCapacity(asyncProperties.getQueueCapacity());
executor.setKeepAliveSeconds(asyncProperties.getKeepAlive());
executor.setThreadNamePrefix("async-kbs-rule-api-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//以用户线程模式运行
executor.setDaemon(false);
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncUncaughtExceptionHandler();
}
public static class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.error("异步异常,方法名:{}", method.getName());
throwable.printStackTrace();
}
}
}

4、application.yml配置属性参数

1
2
3
4
5
6
7
8
9
async:
# 线程池维护线程的最少数量
corePoolSize: 10
# 线程池维护线程的最大数量
maxPoolSize: 64
# 缓存队列
queueCapacity: 1000
# 允许的空闲时间
keepAlive: 10

使用方法

在需要进行异步处理的方法加上@Async注解
1、不带参数返回

1
2
3
4
5
6
@Async
public void test1() throws InterruptedException {
log.info("开始服务1计算");
JSONObject jsonObject = new JSONObject();
jsonObject.put("test1", "value1");
}

2、带参数返回
Future泛型类型根据实际项目需要进行更改

1
2
3
4
5
6
7
8
9
@Async
public Future<JSONObject> test1() throws InterruptedException {
log.info("开始服务1计算");
JSONObject jsonObject = new JSONObject();
jsonObject.put("test1", "value1");
TimeUnit.SECONDS.sleep(3L);
log.info("结束服务1计算");
return new AsyncResult<>(jsonObject);
}

3、异步处理完成后再统一结果返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@GetMapping
public List<JSONObject> testAsync() throws InterruptedException, ExecutionException {
List<JSONObject> list = new ArrayList<>();
Future<JSONObject> test1 = testService.test1();
Future<JSONObject> test2 = testService.test2();
while (true){
if(test1.isDone() && test2.isDone()){
break;
}
}
JSONObject json1 = test1.get();
list.add(json1);
JSONObject json2 = test2.get();
list.add(json2);
return list;
}

Future方法说明:
isDone():判断任务是否执行完成
get():获取异步处理的结果,方法是阻塞的
get(long timeout, TimeUnit unit):在指定的时间内会等待任务执行,超时则抛异常。
cancel():取消任务

文章作者: 微光
文章链接: http://www.guduke.cn/2020/09/19/async/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 微光
打赏
  • 微信
  • 支付宝

评论