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

      

  • 相关阅读:
    Ant安装及环境配置
    tp5 自定义公共函数,前台模板调用
    Linux下查看当前文件大小的命令
    超级好用的视频压缩工具
    ubuntu 安装 gd
    wordpress Error establishing a database connection问题
    wordpress 上传图片出现权限或者http错误
    nginx解决WordPress 上传到服务器后页面404错误的方法
    ubuntu mysql新增用户并开启远程连接
    linux每日命令(21): find命令之exec
  • 原文地址:https://www.cnblogs.com/651434092qq/p/15696669.html
Copyright © 2011-2022 走看看