Spring Cloud Netflix:通过 RequestInterceptor 将主机请求参数传递给 FeignClient
Spring Cloud Netflix : Passing host request parameter via RequestInterceptor to FeignClient
我正在使用 Eureka、Zuul 和 FeignClient 构建一个 Spring 云项目(带有 Spring Boot 1.3.1 的 Brixton.M4),我正在尝试添加多租户支持(租户已确定)按子域:tenant1.myservice.com)。为此,我想以某种方式将原始子域与通过 Feign 从一个服务转发到另一个服务的请求一起传递,但我似乎无法找到正确的方法。
我有一个客户端,它公开一个 @RestController,它调用一个 @FeignClient 与我的后端通信,它通过它自己的 @RestController 向客户端公开服务器操作。
@FeignClient 在服务器上使用与我的@RestController 相同的接口:
@FeignClient(name = "product")
public interface ProductService extends IProductService {
}
我目前正在尝试做的是在 RequestInterceptor 中设置一个 header :
@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"
}
}
}
我的提供者 class 是一个简单的组件,我试图在其中注入一个请求/session 范围 bean :
@Component
public class CurrentTenantProvider {
@Autowired
private CurrentTenant currentTenant;
//...
}
bean(我尝试了 session 和请求范围):
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public CurrentTenant currentTenant() {
return new CurrentTenant();
}
在服务器上,我使用应该捕获 header 值并使用它来定义要连接到哪个数据库的 Hibernate 多租户提供程序:
@Autowired
private HttpServletRequest httpRequest;
@Override
public String resolveCurrentTenantIdentifier() {
return httpRequest.getHeader("TENANT");
}
似乎对服务器的 Feign 调用是在另一个线程中完成的,并且超出了传入请求范围,所以我不确定如何传递该值。
当我在 RequestInterceptor 中对租户值进行硬编码时一切正常,所以我知道其余部分工作正常。
我也看了很多关于 Zuul "X-Forwaded-For" header 的其他帖子,但在服务器收到的请求中找不到它。我也尝试添加一个 ZuulFilter 以将主机名传递给下一个请求,但我看到的是 ZuulFilter 接收了对客户端的原始请求,我可以添加但不是当 Feign 请求发送到后端服务时,即使我在 zuul 中映射它(我猜这是有意的?)。
我不太确定下一步是什么,希望能提供一些建议。
希望它对您有用,但我们在 Spring-Cloud-Sleuth 中做类似的事情,但我们使用 ThreadLocal 在不同的库和方法(包括 Feign + Hystrix)之间传递跨度。
这是一个突出显示行的示例,我们从本地线程检索 Span: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
我正在使用 Eureka、Zuul 和 FeignClient 构建一个 Spring 云项目(带有 Spring Boot 1.3.1 的 Brixton.M4),我正在尝试添加多租户支持(租户已确定)按子域:tenant1.myservice.com)。为此,我想以某种方式将原始子域与通过 Feign 从一个服务转发到另一个服务的请求一起传递,但我似乎无法找到正确的方法。
我有一个客户端,它公开一个 @RestController,它调用一个 @FeignClient 与我的后端通信,它通过它自己的 @RestController 向客户端公开服务器操作。
@FeignClient 在服务器上使用与我的@RestController 相同的接口:
@FeignClient(name = "product")
public interface ProductService extends IProductService {
}
我目前正在尝试做的是在 RequestInterceptor 中设置一个 header :
@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"
}
}
}
我的提供者 class 是一个简单的组件,我试图在其中注入一个请求/session 范围 bean :
@Component
public class CurrentTenantProvider {
@Autowired
private CurrentTenant currentTenant;
//...
}
bean(我尝试了 session 和请求范围):
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public CurrentTenant currentTenant() {
return new CurrentTenant();
}
在服务器上,我使用应该捕获 header 值并使用它来定义要连接到哪个数据库的 Hibernate 多租户提供程序:
@Autowired
private HttpServletRequest httpRequest;
@Override
public String resolveCurrentTenantIdentifier() {
return httpRequest.getHeader("TENANT");
}
似乎对服务器的 Feign 调用是在另一个线程中完成的,并且超出了传入请求范围,所以我不确定如何传递该值。
当我在 RequestInterceptor 中对租户值进行硬编码时一切正常,所以我知道其余部分工作正常。
我也看了很多关于 Zuul "X-Forwaded-For" header 的其他帖子,但在服务器收到的请求中找不到它。我也尝试添加一个 ZuulFilter 以将主机名传递给下一个请求,但我看到的是 ZuulFilter 接收了对客户端的原始请求,我可以添加但不是当 Feign 请求发送到后端服务时,即使我在 zuul 中映射它(我猜这是有意的?)。
我不太确定下一步是什么,希望能提供一些建议。
希望它对您有用,但我们在 Spring-Cloud-Sleuth 中做类似的事情,但我们使用 ThreadLocal 在不同的库和方法(包括 Feign + Hystrix)之间传递跨度。
这是一个突出显示行的示例,我们从本地线程检索 Span: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