SpringBoot 异步编程
文章导读
本文系统讲解 Spring Boot 异步编程的核心技术与实践方案,涵盖从基础使用到高级优化的全链路知识。通过深入剖析 @Async
注解原理、线程池配置策略、异步异常处理机制等关键技术点,结合典型业务场景的代码示例,帮助开发者掌握构建高性能异步系统的核心方法。文章最后提供线程池监控与优化的实战建议。
一、入门篇:基础异步处理
1.1 启用异步支持
在 Spring Boot 主类或配置类添加注解:
java">@SpringBootApplication
@EnableAsync // 开启异步处理支持
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
1.2 基础异步方法
java">@Service
public class OrderService {
@Async // 标记为异步方法
public void processOrderAsync(Order order) {
// 模拟耗时操作
log.info("开始处理订单:{}", order.getId());
sleep(Duration.ofSeconds(3));
log.info("订单处理完成:{}", order.getId());
}
}
代码说明:
- 方法返回类型必须为
void
或Future
类型 - 调用方与被调用方必须在不同类中(AOP 代理限制)
- 默认使用
SimpleAsyncTaskExecutor
(非池化)
二、进阶篇:线程池与高级控制
2.1 线程池配置
# application.yml
spring:
task:
execution:
pool:
core-size: 5
max-size: 20
queue-capacity: 100
keep-alive: 60s
thread-name-prefix: async-exec-
2.2 自定义线程池
java">@Configuration
public class AsyncConfig {
@Bean("customExecutor")
public Executor customTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(200);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("custom-async-");
executor.initialize();
return executor;
}
}
2.3 带返回值的异步
java">@Async("customExecutor")
public CompletableFuture<Report> generateReportAsync() {
return CompletableFuture.supplyAsync(() -> {
// 复杂报表生成逻辑
return reportService.generateComplexReport();
});
}
2.4 异常处理机制
java">public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
log.error("异步方法执行异常: {} - {}", method.getName(), ex.getMessage());
// 发送报警或进行补偿操作
alertService.sendAsyncErrorAlert(method, ex);
}
}
三、精通篇:生产级最佳实践
3.1 异步链路追踪
java">@Async
public CompletableFuture<Void> asyncOperation() {
MDC.put("traceId", TracingContext.getCurrentTraceId());
try {
// 业务逻辑
} finally {
MDC.clear();
}
}
3.2 异步限流控制
java">@Bean
public Executor rateLimitedExecutor() {
Semaphore semaphore = new Semaphore(50); // 并发许可数
return new DelegatedExecutor(Executors.newFixedThreadPool(20),
runnable -> {
semaphore.acquire();
try {
runnable.run();
} finally {
semaphore.release();
}
});
}
3.3 监控指标体系
java">@Bean
public ExecutorServiceMonitor executorMonitor(ThreadPoolTaskExecutor executor) {
return new ExecutorServiceMonitor(executor.getThreadPoolExecutor(),
"order_async_pool");
}
监控关键指标:
- 活跃线程数
- 队列积压量
- 拒绝任务数
- 任务完成平均耗时
四、架构级应用
4.1 异步事件驱动
java">@EventListener
@Async
public void handleOrderEvent(OrderCreatedEvent event) {
// 异步处理领域事件
inventoryService.reduceStock(event.getOrder());
paymentService.processPayment(event.getOrder());
}
4.2 分布式异步协调
java">@Async
public CompletableFuture<Boolean> distributedTask() {
return CompletableFuture.supplyAsync(() -> {
String taskId = distributedService.createTask();
while(true) {
TaskStatus status = distributedService.getStatus(taskId);
if(status.isCompleted()) {
return true;
}
sleep(Duration.ofSeconds(1));
}
});
}
性能优化建议
-
队列容量策略:根据业务特点选择合适队列类型
- CPU密集型:使用有界队列防止内存溢出
- IO密集型:使用无界队列提高吞吐量
-
拒绝策略选择:
- CallerRunsPolicy:保证任务不丢失
- DiscardOldestPolicy:适合实时性要求低的场景
-
线程池预热:
java">@PostConstruct
public void preheatThreadPool() {
IntStream.range(0, corePoolSize)
.forEach(i -> executor.execute(() -> {}));
}
结语
Spring 异步编程能显著提升系统吞吐量,但需注意:
- 避免过度异步化导致线程资源耗尽
- 事务边界需要特殊处理(@Transactional 与 @Async 的协作)
- 异步任务应做好幂等性设计
通过合理配置线程池参数、完善的监控体系以及正确的架构设计,开发者可以构建出高可靠、高性能的异步处理系统。希望本文能帮助读者全面掌握 Spring 异步编程的精髓。