项目中需要调用多个服务,如果使用 open-Feign 串行化调用,响应时间可能会比较长,后续使用了 CompletableFuture 和线程池进行异步调用,但是在调用时,可能存在调用的服务报错,导致整个查询方法直接抛出异常,无法继续后面的操作,注意其他异步调用的任务仍会处理完成。现在我想捕获调用时的异常,且不影响后续的执行。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RpcResult {
private boolean isSuccess;
private String message;
private Object data;
}
@Slf4j
public class AsyncUtil {
/**
* 零元依赖 封装异步调用
* 处理异常信息
*/
public static CompletableFuture<RpcResult> asyncCall(
Supplier<Object> task,
String serviceName,
ThreadPoolExecutor threadPoolExecutor
) {
return CompletableFuture.supplyAsync(()->{
try {
Object data = task.get();
String message = String.format("%s服务调用成功",serviceName);
return new RpcResult(true, message, data);
}catch (Throwable ex) {
String errorMessage = String.format("%s服务调用失败", serviceName);
log.error(errorMessage, ex);
return new RpcResult(false, errorMessage, null);
}
});
}
}
@Test
public void testAsyncUtil(){
PersonRpc personRpc = new PersonRpc();
CompletableFuture<RpcResult> ageF = AsyncUtil.asyncCall(() -> {
Integer age = 21;
int i = 1 / 0;
return age;
}, "ageService", threadPoolExecutor);
CompletableFuture<RpcResult> nameF = AsyncUtil.asyncCall(() -> {
String name = "zhangsan";
int i = 1 / 0;
return name;
}, "nameService", threadPoolExecutor);
CompletableFuture<RpcResult> birthdayF = AsyncUtil.asyncCall(() -> {
LocalDate birthday = LocalDate.parse("2003-10-29");
return birthday;
}, "birthdayService", threadPoolExecutor);
CompletableFuture<Void> allFutures = CompletableFuture.allOf(ageF, nameF, birthdayF);
CompletableFuture<PersonRpc> resultFuture = allFutures.thenApply(v -> {
personRpc.setAge(ageF.join());
personRpc.setName(nameF.join());
personRpc.setBirthday(birthdayF.join());
return personRpc;
});
System.out.println(resultFuture.join());
System.out.println("执行结束");
}
抽象了工具类 AsyncUtil 集中处理调用信息和异常信息,可以看到即使调用服务发生了异常,也能继续执行,发生异常后记录了报错信息且返回给前端状态信息。
正常情况下执行也没有问题