3

我正在用Eureka,Zuul和FeignClient構建一個Spring Cloud項目(Brixton.M4和Spring Boot 1.3.1),我試圖添加多租戶支持(租戶由子域:tenant1.myservice.com標識)。爲此,我想以某種方式將原始子域傳遞給通過Feign從服務轉發到另一個的請求,但我似乎無法找到正確的方式來執行此操作。Spring Cloud Netflix:通過RequestInterceptor將主機請求參數傳遞給FeignClient

我所擁有的是一個公開@RestController的客戶端,它調用@FeignClient與我的後端進行通信,後端通過自己的@RestController向客戶端公開服務器操作。使用相同的接口,我在服務器上@RestController

的@FeignClient:

@FeignClient(name = "product") 
public interface ProductService extends IProductService { 

} 

什麼我目前正在做的是設置在RequestInterceptor頭:

@Component 
public class MultiTenancyRequestInterceptor implements RequestInterceptor { 

    private CurrentTenantProvider currentTenantProvider; 

    @Autowired 
    public MultiTenancyRequestInterceptor(CurrentTenantProvider currentTenantProvider) { 
     this.currentTenantProvider = currentTenantProvider; 
    } 

    @Override 
    public void apply(RequestTemplate template) { 
     try { 
      template.header("TENANT", currentTenantProvider.getTenant()); 
     } catch (Exception e) { 
      // "oops" 
     } 
    } 
} 

我的供應商類是一個簡單的組件,我試圖注入一個請求/會話範圍bean:

@Component 
public class CurrentTenantProvider { 

    @Autowired 
    private CurrentTenant currentTenant; 
    //... 
} 

的豆(我想了會話和請求範圍):

@Bean 
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) 
public CurrentTenant currentTenant() { 
    return new CurrentTenant(); 
} 

在服務器上,我使用的是應該抓住頭值,並用它來定義該DB連接到休眠多租戶提供商:

@Autowired 
private HttpServletRequest httpRequest; 

@Override 
public String resolveCurrentTenantIdentifier() { 
    return httpRequest.getHeader("TENANT"); 
} 

看來Feign對服務器的調用是在另一個線程中完成的,並且不在傳入的請求範圍內,所以我不確定如何傳遞該值。

當我在RequestInterceptor中對租戶值進行硬編碼時,它一切正常,因此我知道其餘的工作正常。

我也看過很多關於Zuul「X-Forwaded-For」標題的文章,並且在服務器收到的請求中找不到它。我也嘗試添加一個ZuulFilter來將主機名傳遞給下一個請求,但是我看到的是對ZuulFilter的原始請求被ZuulFilter拾取,我可以添加,但是當Feign請求被髮送到後端服務時,即使我在zuul中映射它(我想這是有意的?)。

我不知道下一步是什麼,並希望得到一些建議。

+0

就發現,假裝跟蹤項目,這似乎做同樣的事情可能工作:https://github.com/ isthari/spring-cloud-feign-tracing –

回答

3

希望它對您有任何用處,但我們在Spring-Cloud-Sleuth中做的類似,但我們使用ThreadLocal在不同的庫和方法(包括Feign + Hystrix)之間傳遞跨度。

這裏是與突出顯示的行,我們從線程本地檢索跨度的例子:https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceFeignClientAutoConfiguration.java#L123

+0

Marcin,謝謝你的回答!我曾嘗試使用Threadlocal,但我記得它沒有工作,因爲僞裝執行似乎發生在另一個線程中,但我明天再試一次。 –

+1

如果您使用Feign與Hystrix,那麼肯定會發生這種情況。我們通過兩種方法解決了這個問題。 1)Hystrix的全局 - 自定義併發策略 - https:// github。com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/SleuthHystrixConcurrencyStrategy.java#L11 2)Custom只有Feign的方法https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/ Web /客戶端/ TraceFeignClientAutoConfiguration.java#L92 –

+0

我終於得到它遵循您的自定義併發示例工作。我將租戶值存儲在可調用構造函數中,並將其設置回call()中的hystrix線程。非常感謝你的幫助 ! –

相關問題