异步、同步
同步:在发出一个调用时,在得到调用结果之前,该调用不返回(实时处理)。----不相干的业务逻辑会阻塞一些核心的业务逻辑。
异步:在发出一个调用时,这个调用立刻返回,没有返回结果(分时处理)
示例
需求:发布文章时,需要对文章进行自动审核,然后保存文章基础信息。可以将文章自动审核和保存文章分开,对文章自动审核使用异步调用。
- 在文章自动审核的方法上加上@Async注解
/***
* 根据文章ID查询文章,并实现文章内容审核
* @param id
*/
@Async // 方法上添加该注解,表示该方法会异步执行
@Override
public void autoScanWmNews(Integer id) throws UnsupportedEncodingException {
//1)根据文章ID查询文章数据
WmNews wmNews = wmNewsMapper.selectById(id);
//2)调用阿里云实现文本内容审核
// content->提取文本 + title + lables
List<String> textList = parseContent(wmNews.getContent(), "text");
String content = StringUtils.join(textList,wmNews.getTitle(),wmNews.getLabels(), ",");
Map<String, String> textVerifyResult = greenTextScan.verify(content); //ElasticSearch->创建索引->创建自定义分词->将数据存入到ES中
//一篇文章->匹配数据->匹配到-有敏感词
//敏感词很少->100万->存入数据库->加载到程序内存->内存判断
//效率很高->DFA算法
//3)调用MinIO下载图片
List<String> images = parseContent(wmNews.getContent(), "image"); //内容中的图片
String[] imageArray = wmNews.getImages().split(","); //封面图片
images.addAll(Arrays.asList(imageArray)); //内容图片+封面图片
//去重
Set<String> urls = new HashSet<String>();
urls.addAll(images);
List<byte[]> imageBytes = new ArrayList<byte[]>();
for (String url : urls) {
byte[] bytes = fileStorageService.downLoadFile(url);
imageBytes.add(bytes);
}
//4)调用阿里云,实现图片审核
Map<String, String> imageVerifyResult = greenImageScan.verify(imageBytes);
imageVerifyResult.putAll(textVerifyResult);
//5)判断审核结果->审核通过->Feign将文章数据同步到article中
int status = 9;
for (Map.Entry<String, String> entry : imageVerifyResult.entrySet()) {
String value = entry.getValue();
if(value.equals("block")){
//绝对审核不通过
status=2;
break;
}else if(value.equals("review")){
//审核不确定
status=3;
}
}
//判断->当前时间是否小于发布时间,如果小于,则status=8
if(status==9 && wmNews.getPublishTime().getTime()>System.currentTimeMillis()){
status=8;
}
wmNews.setStatus((short) status);
//同步数据到article微服务-200毫秒
if(status==9){
WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
ArticleDto dto = new ArticleDto();
dto.setContent(wmNews.getContent());
dto.setTitle(wmNews.getTitle());
dto.setChannelId(wmNews.getChannelId());
dto.setLayout(wmNews.getType());
dto.setFlag((byte) 0);
dto.setImages(wmNews.getImages());
dto.setLabels(wmNews.getLabels());
dto.setLikes(0);
dto.setCollection(0);
dto.setViews(0);
dto.setComment(0);
dto.setCreatedTime(wmNews.getPublishTime());
dto.setSyncStatus(true);
dto.setChannelName(wmChannel.getName());
//识别修改
if(wmNews.getArticleId()!=null){
dto.setId(wmNews.getArticleId());
}
//dto.setStaticUrl(???);
ResponseResult<Long> saveResult = articleClient.save(dto);
if(wmNews.getArticleId()==null){
wmNews.setArticleId(saveResult.getData());
}
}
//数据同步到数据库
wmNewsMapper.updateById(wmNews);
}
- 在文章保存成功后调用异步方法
@Override
public ResponseResult submit(WmNewsDto dto) throws UnsupportedEncodingException {
//1)将WmNewsDto转换成WmNews
WmNews wmNews = new WmNews();
BeanUtils.copyProperties(dto,wmNews);
//2)需要完善WmNews的数据
wmNews.setCreatedTime(new Date());
//3)status=自动->从内容中提取图片->作为封面[不要超过3张]
if(wmNews.getType()==-1){
//3.1)提取图片
//3.2)将图片作为封面
parseImages(dto);
}
//4)图片【封面】要转换 以逗号隔开
// ["123.jpg","234.jpg"]-->"123.jpg,234.jpg"
String images = StringUtils.join(dto.getImages(), ",");
wmNews.setImages(images);
//5)执行数据更新 status=0 没有发布时间
// status=!0 有发布时间
if(dto.getId()==null){
Integer userId = RequestContextUtil.get("apUserId");
wmNews.setUserId(userId);
//新增
wmNewsMapper.insert(wmNews);
}else{
//修改
wmNewsMapper.updateById(wmNews);
}
//文章审核
wmNewsAutoScanService.autoScanWmNews(wmNews.getId());
return ResponseResult.okResult(null);
}
- 在启动类上加上@EnableAsync注解