项目总结|Feign远程调用和异步调用丢失请求头问题

本文探讨了分布式系统中远程调用与异步调用出现的问题,包括请求头丢失和线程数据共享问题,提供了具体的解决方案,如使用Feign拦截器同步请求头和利用RequestContextHolder共享线程数据。

前言

最近一直在梳理之前做过的项目,想到之前遇到过的一个问题,场景是这样的,在我提交订单时,需要查询用户的地址信息和购物车被勾选的购物项,这样的话,我需要调用两个服务,一个是会员服务,一个是购物车服务。由于用户登陆信息是在整个系统共享的(这里采用分布式session解决),所以我在提交订单的时,调用购物车服务的时候,购物车服务的拦截器会拦截请求,判断用户是否登录。这时候请求头丢失,导致购物车服务拦截器返回用户未登录,但实际上是已经登录过的。还有一个问题是异步调用的时候,老请求线程不共享的问题,导致我业务中获取不到老请求报空指针异常的问题

远程调用出现的问题及解决方案

在分布式项目中,发送请求大致就两种,一种是浏览器访问,第二种是服务与服务之间通过OpenFeign远程调用。浏览器发送请求时,它会带上请求头的信息的,所以不会导致cookie丢失,这样用户真实登录的情况下不会判断未登录的异常情况。深入源码发现,Feign会重新创建一个request,这个请求是没有任何请求头的,这个请求模板会遍历请求拦截器的apply方法来丰富这个请求模板
在这里插入图片描述
看到这个地方就有办法解决了,解决方案就是,我写了一个feign拦截器,这里面注入了一个RequestInterceptor的对象,它是一个接口,我重写了它的apply方法,在里面拿到老请求中的请求头信息,放到这个新的请求模板里,我这里更新的是cookie。来看下代码:

@Configuration
public class GuliFeignConfig {
   
   

    @Bean("requestInterceptor")
    public RequestInterceptor requestInterceptor() {
   
   

        RequestInterceptor requestInterceptor = new RequestInterceptor() {
   
   
            @Override
            public void apply(RequestTemplate template) {
   
   
                //1、使用RequestContextHolder拿到刚进来的请求数据
                ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

                if (requestAttributes != null) {
   
   
                    //老请求
                    HttpServletRequest request = requestAttributes.getRequest();

                    if (request != null) {
   
   
                        //2、同步请求头的数据(主要是cookie)
                        //把老请求的cookie值放到新请求上来,进行一个同步
                        String cookie = request.getHeader("Cookie");
                        template.header("Cookie", cookie);
                    }
                
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值