美文网首页
Feign调用开启Hystrix时无法获取ThreadLocal

Feign调用开启Hystrix时无法获取ThreadLocal

作者: Hogwarts1024 | 来源:发表于2019-01-18 23:07 被阅读0次

    在项目中使用根据请求头处理异常信息国际化的问题,但是在feign调用的时候无法传递请求头,这个问题看了好久最后才知道feign开启hystrix默认会新建一个线程,而我的请求头数据是通过拦截器放到ThreadLocal里的在新线程就无法获取了

    先看一下原来是怎么实现的

    首先是header封装类

    
    @Data
    public class CommonRequestHeader {
    
        /**
         * version 版本号
         */
        private String version;
    
        /**
         * 平台类型
         */
        private String platform;
    }
    
    

    把请求头封装到ThreadLocal中

    @Data
    public class CommonRequestHeaderHolder {
    
        public static final ThreadLocal<CommonRequestHeader> context = new ThreadLocal<>();
    
        public static void clear() {
            context.set(null);
        }
    
        public static void setContext(CommonRequestHeader header) {
            context.set(header);
        }
    
        public static CommonRequestHeader getContext() {
            return context.get();
        }
    }
    

    每次请求的时候通过filter封装把请求头数据放入context中

    但是在feign中开启hystrix的话新线程的ThreadLocal是无法获取主线程的数据的,这个时候就要用到InheritableThreadLocal,只需要改一行代码

    private static final ThreadLocal<CommonRequestData> context = new InheritableThreadLocal<>();
    

    InheritableThreadLocal是ThreadLocal的子类,可以解决父线程和子线程的数据传输问题

    当在主线程开启一个新线程时,会执行Thread的init方法
    init方法中有这么一段代码

            if (inheritThreadLocals && parent.inheritableThreadLocals != null)
                this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    

    当父线程中的inheritableThreadLocal被赋值时,会将当前线程的inheritableThreadLocal变量进行createInheritedMap(),看一下这个方法的具体实现,它会继续调用ThreadLocalMap(parentMap),主要的目的是父线程的变量值赋值给子线程。

    关于ThreadLocal可以看一下 ThreadLocal源码简单了解

    相关文章

      网友评论

          本文标题:Feign调用开启Hystrix时无法获取ThreadLocal

          本文链接:https://www.haomeiwen.com/subject/auoodqtx.html