• 解决Hystrix主线程结束,子线程拿不到request


    在spring-cloud项目中:

    Feign拦截器:

    @Component
    @Slf4j
    public class FeignAccessTokenRequestInterceptor implements RequestInterceptor {
        @Override
        public void apply(RequestTemplate requestTemplate) {
            try {
                HttpSevletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
                requestTemplate.header("REQUEST-SOURCE", request.getHeader("REQUEST-SOURCE"));
            } catch (Exception e) {
                log.info("getRequest fail:{},ignore!", e.getMessage());
            }
        }
    }
    

    使用多线程异步调用微服务,在使用 RequestContextHolder.currentRequestAttributes()).getRequest()  来获取request信息,发现异步调用时,主线程结束后,子线程就获取不到request,会报以下错误信息。

    getRequest fail:

    No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request。

    解决思路:

    1.将主线程的request和session信息放进ThreadLocal里,透传到子线程再去获取。

    2.在开启新线程之前,将servletRequestAttributes设置为子线程共享
     

    继承 HystrixConcurrencyStrategy :

    @Component
    @Slf4j
    public class RequestAttributeStrategy extends HystrixConcurrencyStrategy {
    
        public RequestAttributeStrategy() {
            HystrixPlugins.reset();
            HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
        }
    
        @Override
        public <T> Callable<T> wrapCallable(Callable<T> callable) {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            return new WrappedCallable<>(callable, requestAttributes);
        }
    
        static class WrappedCallable<T> implements Callable<T> {
    
            private final Callable<T> target;
            private final RequestAttributes requestAttributes;
    
            public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
                this.target = target;
                this.requestAttributes = requestAttributes;
            }
    
            @Override
            public T call() throws Exception {
                try {
                    RequestContextHolder.setRequestAttributes(requestAttributes);
                    return target.call();
                } finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        }
    }
    

      

  • 相关阅读:
    汇编与反汇编
    在Mac环境下跑汇编
    使用python-openCV对摄像头捕捉的镜头进行二值化并打上文字
    关于js中的setTimeout和setInterval
    在MacOX下安装python-opencv
    为什么在保护模式下IA-32处理器最高可访问4GB的内存
    Mac上常用的一些命令
    说说chrome上的JS调试
    Steganography-图片隐写术
    Makefile-filter和filter-out
  • 原文地址:https://www.cnblogs.com/651434092qq/p/15696669.html
Copyright © 2020-2023  润新知