java解决Feign异步情况丢失上下文问题
在微服务的开发中,我们经常需要服务之间的调用,并且为了提高效率使用异步的方式进行服务之间的调用,在这种异步的调用情况下会有一个严重的问题,丢失上文下

通过以上图片可以看出异步丢失上下文的原因是不在同一个线程,所有数据不能共享,Wie了解决这个问题,我们就需要把之前线程的请求头上下文,在次存放到其他线程的请求头上下文就行,具体实现如下:

案例:feign异步获取订单明细的案例代码
/**
* 获取订单明细的vo
* @return
*/
@Override
public OrderConfirmVo orderConfirm() {
MemberResponseVo member = OrderInterceptor.threadLocal.get();
OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
System.out.println("主线程:"+ Thread.currentThread().getId());
//获取主线程的请求头信息
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//考虑到效率问题 使用异步编排
CompletableFuture<Void> getAddress = CompletableFuture.runAsync(() -> {
//子线程中设置添加主线程的请求头信息 信息共享 否则远程调用异步处理丢失请求头信息
RequestContextHolder.setRequestAttributes(requestAttributes);
System.out.println("address:"+ Thread.currentThread().getId());
//远程获取地址信息
List<MemberAddressVo> address = memberFeignService.getAddress(member.getId());
orderConfirmVo.setAddress(address);
}, executor);
CompletableFuture<Void> getItem = CompletableFuture.runAsync(() -> {
//子线程中设置添加主线程的请求头信息 信息共享 否则远程调用异步处理丢失请求头信息
RequestContextHolder.setRequestAttributes(requestAttributes);
System.out.println("item:"+ Thread.currentThread().getId());
//远程获取购物项
List<OrderItemVo> currentUserCartItems = cartFeignService.getCurrentUserCartItems();
orderConfirmVo.setItems(currentUserCartItems);
}, executor).thenRunAsync(()->{
List<OrderItemVo> items = orderConfirmVo.getItems();
//获取所有商品的id
List<String> collect = items.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
List<Long> skuIds = collect.stream().map(item -> {
return Long.parseLong(item);
}).collect(Collectors.toList());
R<List<SkuHasStockVo>> skusHasStock = wmsFeignService.getSkusHasStock(skuIds);
List<SkuHasStockVo> data = skusHasStock.getData(new TypeReference<List<SkuHasStockVo>>() {
});
if(data!= null){
Map<Long, Boolean> collect1 = data.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
orderConfirmVo.setStocks(collect1);
}
},executor);
//异步编排完成之后执行后续操作
try {
CompletableFuture.allOf(getAddress,getItem).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
orderConfirmVo.setIntegration(member.getIntegration());
orderConfirmVo.setPayPrice(orderConfirmVo.getPayPrice());
orderConfirmVo.setTotal(orderConfirmVo.getTotal());
//TODO 放重处理 生成token令牌储存在redis
String token = UUID.randomUUID().toString().replace("-", "");
orderConfirmVo.setOrderToken(token);
redisTemplate.opsForValue().set(OrderConstant.ORDER_TOKEN+member.getId(),token);
return orderConfirmVo;
}到此这篇关于java解决Feign异步情况丢失上下文问题的文章就介绍到这了,更多相关java Feign异步丢失上下文内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java中Elasticsearch 实现分页方式(三种方式)
Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎,这篇文章主要介绍了Elasticsearch实现分页的3种方式,需要的朋友可以参考下2022-07-07
IDEA创建Maven项目后报错不出现src文件夹的情况解决
最近刚开始学习maven,正准备使用idea创建一个maven项目练手,却发现自己创建的maven项目始终没有src目录,下面这篇文章主要给大家介绍了关于IDEA创建Maven项目后报错不出现src文件夹的情况解决,需要的朋友可以参考下2023-05-05
Spring Boot 整合RocketMq实现消息过滤功能
这篇文章主要介绍了Spring Boot 整合RocketMq实现消息过滤,本文讲解了RocketMQ实现消息过滤,针对不同的业务场景选择合适的方案即可,需要的朋友可以参考下2022-06-06
spring 和 idea 建议不要使用 @Autowired注解的原因解析
@Autowired 是Spring框架的注解,而@Resource是JavaEE的注解,这篇文章主要介绍了spring和idea建议不要使用@Autowired注解的相关知识,需要的朋友可以参考下2023-11-11
详解spring cloud构建微服务架构的网关(API GateWay)
这篇文章主要介绍了详解spring cloud构建微服务架构的网关(API GateWay),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-01-01


最新评论