场景:图片是上传到腾讯云cos,上传后需要经过腾讯云的审核,审核后才能获取上传结果,主线程等待结果会占用大量的系统资源。
解决方案:通过异步请求来处理,所谓异步请求,就是在当前线程调用之后直接返回,继续处理其余任务,当前调用处理成功之后再经过一个回调线程来处理返回结果。
我们通过实现Callable接口的call方法来定义Web请求返回结果的任务,并通过WebAsyncTask来执行任务,当调用任务以后立即返回,即可并行执行其他任务,最终当webAsyncTask执行完成以后,Web请求获得返回,详情如下:
代码:
@ResponseBody
public WebAsyncTask<RespDTO> fs_out_files_upload(HttpServletRequest request) throws Exception {
RespDTO baseRespDTO = RespDTO.getInstance(null);
MultipartFile fileList = ((MultipartHttpServletRequest) request).getFile("file");
log.info("外部线程:" + Thread.currentThread().getName());
Callable<RespDTO> result = () -> {
String requestId= IdUtil.fastSimpleUUID();
MDC.put("requestId", requestId);
log.info("内部线程:" + Thread.currentThread().getName());
try {
return commonFileService.fsOutFilesUpload(fileList);
} catch (Exception e) {
log.error("上传文件文件异常", e);
}
log.info("内部线程返回:" + Thread.currentThread().getName());
baseRespDTO.setMsg("处理失败");
return baseRespDTO;
};
WebAsyncTask<RespDTO> wat = new WebAsyncTask<RespDTO>(5000L, result);
wat.onTimeout(() -> {
log.error("文件上传超时,内部线程:" + Thread.currentThread().getName());
baseRespDTO.setMsg("处理失败,超时");
baseRespDTO.setSubMsg("文件上传失败");
return baseRespDTO;
});
wat.onError(() -> {
// 错误回调
log.error("文件上传发生错误,内部线程:" + Thread.currentThread().getName());
baseRespDTO.setMsg("处理失败,上传出错");
baseRespDTO.setSubMsg("文件上传失败");
return baseRespDTO;
});
return wat;
}
}