Feign远程调用
请求头丢失问题
场景:从购物车结算生成订单
从购物车页跳转请求 /toTrade 调用订单服务confirmOrder生成订单
思路:
-
首先为订单服务编写拦截器判断是否登录,当从购物车的请求过来时根据Request中的Session来判断登录状态,然后把从Session中获取到的用户数据存到本地线程变量
ThreadLocal中 -
调用
confirmOrder方法
(1)首先从ThreadLocal中拿到用户数据
(2)调用用户服务memberFeignService.getAddress(Long userId) 去查询返回收货地址等信息
(3)调用购物车服务cartFeignService.getCurrentCartItems()查询当前用户购物车中已选中结算的商品
问题:
过程(3)服务调用的方法并没有传递什么用户id这类实质性参数,而是采用登录后放大Session作用域然后共享的方案,问题就出在这里,Feign远程调用会重新创建一个Request请求,而这个请求的header不会携带cookie,所以在购物车服务那里请求来了拦截判断用户状态时是空的。
解决:
Feign在远程调用时会先通过拦截器,然后根据模板构造一个请求,这个模板默认是空的
可以重写这个拦截器,在使用模板阶段往里面存放
header携带cookie
为了加快回显的速度查询用户地址信息,购物车这两个过程一定是要异步执行的,那么上一步拦截器中RequestContextHolder.getRequestAttributes()从上下文获取就会失效,RequestContextHolder是从当前Request请求线程的本地线程变量ThreadLocal中获取信息,而异步执行用是用的线程池里的线程,所以要同步一下异步任务里的请求线程的数据