openFeign问题总结及解决、session共享、ThreadLocal使用

ThreadLocal 同一线程数据共享

同一线程指:请求到连接器到controoler到service执行时同一个线程

ThreadLocal 调用setget方法可以实现统一线程的数据共享

public static ThreadLocal<MemberResponseVo> loginUser = new ThreadLocal<>();
loginUser.set(Userr);
loginUser.get();

openFeign

1.feign远程调用丢失请求头问题

原因:feign在请求前会构造请求,执行拦截器的进一步构造进行新请求增强,构造的对象没有请求头

解决:加上feign远程调用的拦截器

@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);
                    }
                }
            }
        };

        return requestInterceptor;
    }
}

2.feign丢失上下文问题

原因: 开启异步编排导致丢失上下文----因为用的ThreadLocal同一线程数据共享,所以异步编排就会导致线程多个,子线程丢失上下文从而获取不到主线程的ThreadLocal共享数据
解决:
1. 在主线程中获取上下文
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
2.在子线程中设置主线程的上下文
RequestContextHolder.setRequestAttributes(requestAttributes);

session共享

使用session-redis 储存session

1.pom 依赖

      <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2.主启动类加注解

@EnableRedisHttpSession //整合redis作为session的存储
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class GulimallAuthServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallAuthServerApplication.class, args);
    }

}

3. 配置cookie和域

@Configuration
public class GulimallSessionConfig {

    @Bean // redis的json序列化
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }

    @Bean // cookie
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setCookieName("GULISESSIONID"); // cookie的键
        serializer.setDomainName("gulimall.com"); // 扩大session作用域,也就是cookie的有效域
        return serializer;
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadLocalJava 中的一个类,用于实现线程本地存储。它可以让你在每个线程中存储一些数据,这些数据对于其它线程而言是不可见的,每个线程都可以独立地操作自己的数据,互不干扰。ThreadLocal 主要用于解决线程并发访问共享变量的问题ThreadLocal使用方法很简单,只需要创建一个 ThreadLocal 对象,然后调用它的 set()、get() 方法即可。例如: ``` ThreadLocal<String> threadLocal = new ThreadLocal<>(); threadLocal.set("Hello World"); String value = threadLocal.get(); ``` 这段代码创建了一个 ThreadLocal 对象,然后存储了一个字符串 "Hello World" 到当前线程ThreadLocal 中,最后又取出了这个字符串。 但是,使用 ThreadLocal 也会存在一些问题。其中最常见的问题就是内存泄漏。由于 ThreadLocal 存储的数据是线程本地的,因此如果线程池中的线程没有及时地清理 ThreadLocal 中的数据,就会导致内存泄漏。解决这个问题的方法是在使用ThreadLocal 后及时调用 remove() 方法来清理数据。 还有一个问题线程复用。在线程池中,线程可能会被重复使用,如果使用ThreadLocal,那么在下一次使用时,ThreadLocal 中的数据可能会残留上一次使用的数据,导致错误。解决这个问题的方法是在使用ThreadLocal 后及时调用 remove() 方法来清理数据,或者使用 InheritableThreadLocal,它可以让子线程继承父线程ThreadLocal 数据。 总之,ThreadLocal使用需要注意内存泄漏和线程复用等问题,正确使用可以有效地解决线程并发访问共享变量的问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值