公共代码:
@Data
public class Customer {
private Long id;
private String name;
private Long score;
private String orderInfo;
}
业务类中模拟微服务接口的方法:
private String getName() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "yzh";
}
private Long getScore() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return 60l;
}
private String getOrderInfo() {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "orderInfo";
}
控制类:
@Autowired
private CustomerService customerService;
@GetMapping("/find1")
public Customer find1(){
//串行调用
return customerService.find();
}
@GetMapping("/find2")
public Customer find2(){
//异步调用
return customerService.find2();
}
当在微服务中调用多个接口获取一个返回值的时候,串行调用耗时可能很大,接口响应慢。
如:
业务类:
public Customer find() {
long start = System.currentTimeMillis();
Customer customer = new Customer();
customer.setId(1l);
customer.setName(getName());
customer.setScore(getScore());
customer.setOrderInfo(getOrderInfo());
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
return customer;
}
结果图:
优化:使用 CompletableFuture
来实现并发异步操作,来优化获取客户数据。
在此状况下通过并发执行三个独立的任务(设置客户的姓名、积分和订单信息),可以显著减少总的执行时间。
业务类:
@Autowired
//此处为自定义的线程池Bean。 可以创建一个线程池代替
private ThreadPoolTaskExecutor pool;
@Override
public Customer find2() {
long start = System.currentTimeMillis();
Customer customer = new Customer();
customer.setId(1l);
CompletableFuture<Void> name = CompletableFuture.runAsync(() -> {
customer.setName(getName());
}, pool).exceptionally(ex -> {
//异常情况下返回为null保证业务流程
return null;
});
CompletableFuture<Void> score = CompletableFuture.runAsync(() -> {
customer.setScore(getScore());
}, pool).exceptionally(ex -> {
return null;
});
CompletableFuture<Void> order = CompletableFuture.runAsync(() -> {
customer.setOrderInfo(getOrderInfo());
}, pool).exceptionally(ex -> {
return null;
});
// 等待所有任务完成
CompletableFuture.allOf(name, score, order).join();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
return customer;
}
执行结果:
总结:
使用CompletableFuture
来实现并发异步操作,将串行调用改为并行调用,耗时降为最长响应接口的耗时。