feign之間傳遞oauth2-token的問題和解決~續

之前寫過關於修改hystric的隔離《feign之間傳遞oauth2-token的問題和解決》方式來在feign調用各個微服務中傳遞token,修改爲SEMAPHORE之後,會有一些性能的問題,可能出現請求積壓,請求雪崩等問題,所以今天需要使用另一種方法,就是通過自定義的隔離對象重寫wrapCallable方法來實現。

  • CustomFeignHystrixConcurrencyStrategy代碼
    import com.netflix.hystrix.strategy.HystrixPlugins;
    import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.annotation.Primary;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
     
    import java.util.concurrent.Callable;
     

    @Slf4j
    @Primary
    @Component
    public class CustomFeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
     
        public CustomFeignHystrixConcurrencyStrategy() {
            try {
     
                HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
     
            } catch (Exception e) {
                log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
            }
        }
     
        @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;
            }
     
            /**
             * feign opens the fuse (hystrix): feign.hystrix.enabled=ture, and uses the default signal isolation level,
             * The HttpServletRequest object is independent of each other in the parent thread and the child thread and is not shared.
             * So the HttpServletRequest data of the parent thread used in the child thread is null,
             * naturally it is impossible to obtain the token information of the request header In a multithreaded environment, call before the request, set the context before the call
             *
             * feign啓用了hystrix,並且feign.hystrix.enabled=ture。採用了線程隔離策略。
             * HttpServletRequest 請求在對象在父線程和子線程中相互獨立,且不共享
             * 所以父線程的 HttpServletRequest 在子線程中爲空,
             * 所以通常 在多線程環境中,在請求調用之前設置上下文
             * @return T
             * @throws Exception Exception
             */
            @Override
            public T call() throws Exception {
                try {
                    // Set true to share the parent thread's HttpServletRequest object setting
                    RequestContextHolder.setRequestAttributes(requestAttributes, true);
                    return target.call();
                } finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        }
    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章