Как пересылать заголовки при использовании Zuul, Hystrix (и Feign) с Spring Cloud HATEOAS? - PullRequest
0 голосов
/ 26 марта 2019

Контекст

Мое приложение микро-сервисов основано на spring-cloud: шлюз zuul настроен перед двумя микро-сервисами: service-a и service-b .

Один из моих API требует, чтобы service-a запросы service-b ;Для этого я использую feign.

Zuul отправляет X-FORWARDED-* заголовки сервисам, чтобы они правильно переписывали ссылки HATEOAS (когда сервисы настроены с ForwardedHeaderFilter).

Моя проблема в том, что сервисы взаимодействуют друг с другом, используя Feign, что зависит от Hystrix.Hystrix создает новый поток для каждого запроса (мы не используем конфигурацию SEMAPHORE), поэтому запрос в RequestContextHolder Spring теряется в запросе Feign от service-a до service-b , я не могу больше обогатить запрос feign перехватчиком feign, так как исходный запрос потерян.

Некоторые потенциальные решения

Теперь токен авторизации пересылкиподдерживается напрямую Spring с параметром hystrix.shareSecurityContext: true

Конфигурация "из коробки" отсутствует, чтобы Hystrix разделял запрос между потоками.

Решением может быть реализовать мой собственный HystrixConcurrencyStrategy, который является классом из netflix.hystrix.Моя последняя находка - это Запрос Pull , который был отправлен Spring-cloud-netflix, но, к сожалению, не интегрирован.

Я могу попытаться скопировать код запроса Pull и создатьбин, так же, как то, что написал "eacdy":

@Bean
public RequestAttributeHystrixConcurrencyStrategy hystrixRequestAutoConfiguration() {
    return new RequestAttributeHystrixConcurrencyStrategy();
}

Есть ли более простое решение для перенаправления заголовков из Zuul с Hystrix?

Я предполагаю, что то, что я пытаюсьЭто очень стандартно при использовании микро-сервисов Zuul, Hystrix и HATEOAS, которые взаимодействуют друг с другом, так что, может быть, что-то уже существует (и что я не смог найти)?

Спасибо!

1 Ответ

0 голосов
/ 09 апреля 2019

Я думал, что это довольно распространенная вещь, но после долгих исследований я не смог найти способ автоматической пересылки заголовков X-FORWARDED-* с помощью Feign и Hystrix.

Итак, я искал другое решение, которое работает и довольно чисто:

  • В клиенте Feign от service-a до service-b я объявил специальную конфигурацию "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.

  • Вы должны игнорировать эту конфигурацию при сканировании компонентов Spring Boot, даже если для этого требуется аннотация @Configuration, поэтому поместите ее в пакет ignorescan и в своем основном загрузочном классе Spring используйте:
@ComponentScan(basePackages = { "com.myservice" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.myservice.ignorescan.*"))

В конце заголовки Forward будут добавлены, если для параметра gatewayEnabled установлено значение true, а вызов API для шлюза вернет правильные ссылки HATEOAS.

...