// 精心制作的弹性解决方案
public UserDashboardDTO getDashboard(long userId) {
// 为每个服务调用设置合理的超时
Duration timeout = Duration.ofSeconds(2);
// 使用自定义线程池,而不是ForkJoinPool.commonPool()
Executor timeoutExecutor = Executors.newFixedThreadPool(3);
try {
// 使用单独的CompletableFuture处理每个可能的失败
CompletableFuture<Optional<User>> userFuture =
CompletableFuture.supplyAsync(() -> {
try {
return Optional.of(userService.getById(userId));
} catch (Exception e) {
log.warn("获取用户{}失败", userId, e);
return Optional.<User>empty();
}
}, timeoutExecutor)
.orTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS)
.exceptionally(ex -> Optional.empty());
CompletableFuture<List<Order>> ordersFuture =
CompletableFuture.supplyAsync(() -> {
try {
return orderService.getRecentForUser(userId, 5);
} catch (Exception e) {
log.warn("获取用户{}订单失败", userId, e);
return Collections.<Order>emptyList();
}
}, timeoutExecutor)
.orTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS)
.exceptionally(ex -> Collections.emptyList());
CompletableFuture<Integer> reviewsFuture =
CompletableFuture.supplyAsync(() -> {
try {
return reviewService.countByUser(userId);
} catch (Exception e) {
log.warn("获取用户{}评论数量失败", userId, e);
return 0;
}
}, timeoutExecutor)
.orTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS)
.exceptionally(ex -> 0);
// 等待所有操作完成,但每个都有优雅的降级
CompletableFuture.allOf(userFuture, ordersFuture, reviewsFuture).join();
return new UserDashboardDTO(
userFuture.join().orElse(null), // 可能为null,前端需要处理
ordersFuture.join(), // 永远不为null,最坏情况是空列表
reviewsFuture.join() // 永远不为null,最坏情况是0
);
} finally {
// 清理自定义执行器
if (timeoutExecutor instanceof ExecutorService) {
((ExecutorService) timeoutExecutor).shutdown();
}
}
}