前言
- Servlet 3.0之前:HTTP请求由单一线程处理。
- Servlet 3.0之后:支持异步处理,提高系统吞吐量。
SpringBoot 异步接口实现方式
- AsyncContext:Servlet层级,不常用。
- Callable:使用
java.util.concurrent.Callable
。 - WebAsyncTask:Spring封装的
Callable
,提供回调功能。 - DeferredResult:延迟结果设置,适用于结果生成可能在其他线程。
Callable 实现
- Controller返回:
Callable<String>
。 - 处理过程:
- Spring MVC调用
request.startAsync()
。 - 使用
AsyncTaskExecutor
在单独线程处理。 - 释放Servlet容器线程,保持response状态。
- Callable结果产生后,请求返回Servlet容器完成处理。
- Spring MVC调用
WebAsyncTask 实现
- 特点:提供超时、错误和完成回调。
- 示例:
@GetMapping("/webAsyncTask") public WebAsyncTask<String> webAsyncTask() {WebAsyncTask<String> result = new WebAsyncTask<>(30003, () -> "success");result.onTimeout(() -> {log.info("timeout callback");return "timeout callback";});result.onCompletion(() -> log.info("finish callback"));return result; }
DeferredResult 实现
- 特点:结果可能在其他线程设置。
- 示例:
@GetMapping("/testDeferredResult") public DeferredResult<String> testDeferredResult(){DeferredResult<String> deferredResult = new DeferredResult<>();deferredResultMap.put("test", deferredResult);return deferredResult; }
- 处理过程:
- 保存
DeferredResult
。 - Spring MVC调用
request.startAsync()
。 - 应用程序在其他线程设置
DeferredResult
值。
- 保存
线程池配置
- 自定义线程池:提供异步请求使用的线程池。
- 配置示例:
@Bean("mvcAsyncTaskExecutor") public AsyncTaskExecutor asyncTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(10);executor.setThreadNamePrefix("fyk-mvcAsyncTask-Thread-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());executor.setWaitForTasksToCompleteOnShutdown(true);executor.setAwaitTerminationSeconds(30);executor.initialize();return executor; }
异步请求配置
- 配置类:
FykWebMvcConfigurer
实现WebMvcConfigurer
。 - 超时时间设置:
configurer.setDefaultTimeout(60001);
使用异步请求的场景
- 适用场景:请求中CPU大量时间处于休息状态。
- 不适用场景:CPU持续高负荷运算。
结论
异步请求通过释放主线程提高吞吐量,但需合理使用以避免增加耗时。了解异步接口实现有助于优化SpringBoot应用性能。