最近在项目中使用CompletableFuture做了异步处理,但是在controller层返回时遇到一个尴尬的问题,如果按照之前的处理方式,返回普通对象,势必要进行join或get,这个会造成forkJoin线程阻塞,影响吞吐量不说,如果请求量较大,可能会把整个程序拖垮。
AsyncController 就能较好的解决上面的问题,虽然与之前的方式相比,响应时间不会增加,但好处是线程在等待第一个请求完成时不会被阻止响应其他请求。
更多内容请参考:https://blog.csdn.net/baidu_22254181/article/details/80789090
下面是一段例子:
这样包装之后,spring会自动进行异步处理,将方法以及响应的任务交给spring默认或者你定义的taskExecutor线程池bean执行,原本tomcat负责处理请求的线程返回tomcat线程池,不影响servlet接受请求的能力。要阻塞也是taskExecutor线程池里的线程,而不是tomcat线程池的线程。
@RestController
@Slf4j
public class TestController {
private final static long TIMEOUT = 10 * 1000L;
@Autowired
private SearchService searchService;
@RequestMapping("/search")
@ResponseBody
public WebAsyncTask<JsonResult> search(@RequestBody Request request){
try{
CompletableFuture<SearchResult> future = searchService.search(request);
WebAsyncTask<JsonResult> asyncTask = new WebAsyncTask<>(TIMEOUT,
() -> ResponseBuilder.buildSuccess(future.join()));
return asyncTask;
}catch (Exception e){
WebAsyncTask<JsonResult> asyncTask = new WebAsyncTask<>(TIMEOUT,
() -> ResponseBuilder.buildFail(e.getMessage()));
return asyncTask;
}
}
}
微信公众号:二虎程序