在Spring Cloud HATEOAS中使用Zuul,Hystrix(和Feign)时,如何转发标头?

时间:2019-03-26 12:21:10

标签: spring-cloud netflix-zuul hystrix spring-hateoas spring-cloud-feign

上下文

我的微服务应用程序基于spring-cloud:在两个微服务( service-a service- b

我的一个API要求 service-a 请求 service-b ;我为此使用zuul

Zuul向服务发送feign头,以便它们正确重写HATEOAS链接(当服务配置有X-FORWARDED-*时)。

我的问题是服务使用ForwardedHeaderFilter依赖于Feign相互通信。 Hystrix为每个请求创建一个新线程(我们不使用SEMAPHORE配置),因此Spring的Hystrix中的请求在 service-a 的Feign请求中丢失了到 service-b ,由于原始请求丢失,我无法再使用RequestContextHolder拦截器来丰富feign请求。

一些潜在的解决方案

Spring现在直接通过参数feign支持转发授权令牌

没有任何“开箱即用”的配置可以让Hystrix在线程之间共享请求。

一个解决方案可能是implement my own HystrixConcurrencyStrategy,它是netflix.hystrix的一个类。 我的最新发现是这个Pull Request已发送到spring-cloud-netflix,但不幸的是没有集成。

我可以尝试复制Pull请求的代码,并创建一个bean,就像“ eacdy”写道:

hystrix.shareSecurityContext: true

有没有更简单的解决方案,可以将@Bean public RequestAttributeHystrixConcurrencyStrategy hystrixRequestAutoConfiguration() { return new RequestAttributeHystrixConcurrencyStrategy(); } 的标头与Zuul一起转发?

我想我尝试使用相互通信的HystrixZuulHystrix微服务时,这是非常标准的,所以也许有些东西已经存在(并且我找不到)?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为这是一件很平常的事情,但是经过大量研究,我找不到用X-FORWARDED-*Feign自动转发Hystrix标头的方法

因此,我正在寻找另一个可行且非常干净的解决方案:

  • 在从{em> service-a 到 service-b Feign客户端中,我声明了一个特定的配置“ ServiceBFeignConfig”,除了转发令牌,还添加与网关相对应的X-Forwarded-*标头:
@Configuration
public class ServiceBFeignConfig {

    @Autowired
    private ApplicationProperties applicationProperties;

    @Bean
    public RequestInterceptor requestTokenBearerInterceptor() {
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate requestTemplate) {
                OAuth2AuthenticationDetails details =
                        (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
                requestTemplate.header("Authorization", "bearer " + details.getTokenValue());

                if (applicationProperties.getFeign().getGatewayEnabled()) {
                    requestTemplate.header("X-Forwarded-Host", applicationProperties.getFeign().getGatewayHost());
                    requestTemplate.header("X-Forwarded-Port", applicationProperties.getFeign().getGatewayPort());
                    requestTemplate.header("X-Forwarded-Proto", applicationProperties.getFeign().getGatewayProtocol());
                    requestTemplate.header("X-Forwarded-Prefix", applicationProperties.getFeign().getServiceBPrefix());
                }
            }
        };
    }

}

您可以看到在属性文件中配置了网关主机和端口(在我的情况下,该主机和端口由Spring Cloud Config提供)。在这些文件中还设置了 service-b 前缀。

仅在属性文件中设置了“ gatewayEnabled”属性时,才添加这些标头。

  • 即使需要@Configuration注释,也必须从Spring Boot的组件扫描中忽略此配置,因此请将其放在“ ignorescan”包中,并在主Spring Boot类上使用:< / li>
@ComponentScan(basePackages = { "com.myservice" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.myservice.ignorescan.*"))

最后,如果将gatewayEnabled设置为true,则将添加Forward标头,并且对网关的API调用将获得正确的HATEOAS链接。