前言
- 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應用性能。