Spring mvc Spring Cloud Netflix:通过RequestInterceptor将主机请求参数传递给FaignClient
我正在用Eureka、Zuul和FaignClient构建一个Spring云项目(Brixton.M4和Spring Boot 1.3.1),我试图在其中添加多租户支持(租户由子域确定:tenant1.myservice.com)。为了做到这一点,我想通过某种方式将原始子域传递给通过Feign从一个服务转发到另一个服务的请求,但我似乎无法找到正确的方法 我拥有的是一个客户端,它公开@RestController,调用@FeignClient与我的后端通信,后端通过自己的@RestController向客户端公开服务器操作 @FeignClient在服务器上使用与我的@RestController相同的接口:Spring mvc Spring Cloud Netflix:通过RequestInterceptor将主机请求参数传递给FaignClient,spring-mvc,spring-boot,spring-cloud,netflix-zuul,netflix-feign,Spring Mvc,Spring Boot,Spring Cloud,Netflix Zuul,Netflix Feign,我正在用Eureka、Zuul和FaignClient构建一个Spring云项目(Brixton.M4和Spring Boot 1.3.1),我试图在其中添加多租户支持(租户由子域确定:tenant1.myservice.com)。为了做到这一点,我想通过某种方式将原始子域传递给通过Feign从一个服务转发到另一个服务的请求,但我似乎无法找到正确的方法 我拥有的是一个客户端,它公开@RestController,调用@FeignClient与我的后端通信,后端通过自己的@RestControll
@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"
}
}
}
我的provider类是一个简单的组件,我试图在其中注入一个请求/会话范围bean:
@Component
public class CurrentTenantProvider {
@Autowired
private CurrentTenant currentTenant;
//...
}
bean(我尝试了会话和请求范围):
在服务器上,我使用Hibernate multitenant provider来捕获头值,并使用它定义要连接到的DB:
@Autowired
private HttpServletRequest httpRequest;
@Override
public String resolveCurrentTenantIdentifier() {
return httpRequest.getHeader("TENANT");
}
似乎对服务器的假调用是在另一个线程中完成的,并且超出了传入的请求范围,所以我不确定如何传递该值
当我在RequestInterceptor中硬编码租户值时,一切都很好,因此我知道其余的都正常工作
我也看过很多关于Zuul“X-Forwaded-For”头的帖子,但在服务器上收到的请求中找不到它。我也尝试过添加一个ZuulFilter来将主机名传递给下一个请求,但我看到的是,发送给客户端的原始请求是由ZuulFilter接收的,我可以添加,但不能在伪请求发送到后端服务时添加,即使我在zuul中映射它(我想这是有意的?)
我真的不确定下一步是什么,希望能有一些建议 希望它对您有用,但我们在Spring Cloud Sleuth中也做了类似的工作,但我们使用ThreadLocal在不同的库和方法(包括Feign+Hystrix)之间传递跨度
下面是一个突出显示行的示例,我们从线程本地检索跨度:Marcin,感谢您的回答!我确实尝试过使用Threadlocal,但我记得它也不起作用,因为假装执行似乎发生在另一个线程中,但我明天会再试一次。如果你将假装与Hystrix一起使用,那么肯定会发生这样的情况。我们通过两种方法解决了这个问题。1) Hystrix的全局-自定义并发策略-2)仅用于外部的自定义方法我最终按照您的自定义并发示例使其工作。我将租户值存储在可调用构造函数中,并在call()中将其设置回hystrix线程。非常感谢你的帮助!伟大的这正是需要做的:)这是在线程之间传递东西的方式。如果你问这个问题,Sleuth中的伪代码已经改变了很多。无论如何,对于boot 1.4来说,一切都应该可以正常工作。我们刚刚发现,伪跟踪项目似乎做了一些类似的事情,可能会工作:
@Autowired
private HttpServletRequest httpRequest;
@Override
public String resolveCurrentTenantIdentifier() {
return httpRequest.getHeader("TENANT");
}