feign調用自動轉發請求頭header


那么如何解決請求頭的傳遞問題呢?

一 最容易想到的方法是在轉發和請求時主動將header參數傳入。

通過在controller中設置RequestHeader參數。這種方法的弊端是每次都得修改controller中的api方法,耦合性高,一旦需要增加header參數,則所有涉及到的controller方法都要調整一遍。

二 比較通用的方法是使用攔截器,在轉發請求時,統一添加header信息。

@Component
public class FeignClientsConfigurationCustom implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        if (null != attributes) {
            HttpServletRequest request = attributes.getRequest();
            if (null != request) {
                Enumeration<String> headerNames = request.getHeaderNames();
                if (headerNames != null) {
                    while (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String values = request.getHeader(name);
                        requestTemplate.header(name, values);
                    }
                }
            }
        }
    }
}

但是,如果開啟了hystrix隔離策略,則會影響header參數的轉發。

hystrix的默認隔離策略是線程隔離。

在這種情況下,轉發調用和真正請求的不是同一個線程,因此沒有辦法獲取到ThreadLocal中的數據。

此時,ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();  拿到的attributes是null,因為這里用到了ThreadLocal。

因此在線程隔離策略下,服務端拿不到header信息。那么怎么辦呢?

解決方案一:修改默認隔離策略為信號量模式

hystrix.command.default.execution.isolation.strategy=SEMAPHORE,這樣的話轉發線程和請求線程實際上是一個線程。但是這種方法有些弊端,hystrix官方不建議使用信號量模式。

解決方案二:自定義hystrix隔離策略

思路是將現有的並發策略作為新並發策略的成員變量。在新並發策略中,返回現有並發策略的線程池、Queue,將策略加到Spring容器即可。目前,Spring Cloud Sleuth以及Spring Security都通過該方式傳遞 ThreadLocal 對象。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM