zoukankan      html  css  js  c++  java
  • 解决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();
                }
            }
        }
    }
    

      

  • 相关阅读:
    SpringBoot配置文件加载位置及顺序
    linux之开通FTP服务(喂饭级)
    linux之chmod授权
    mysql动态查询上周的数据
    hibernate解读之session--基于最新稳定版5.2.12
    阿里java开发手册中命名规约解读之DO/BO/DTO/VO/AO
    JSP最常用的五种内置对象(out,request,response,session,application)
    JSP执行过程分析
    web.xml解析
    MVC脚手架(一)之javabean+jsp+servlet+jdbc
  • 原文地址:https://www.cnblogs.com/651434092qq/p/15696669.html
Copyright © 2011-2022 走看看