Мое приложение микросервисов основано на spring-cloud: шлюз zuul настроен перед двумя микросервисами: сервис-а и сервис-б.
Один из моих API требует, чтобы сервис-а запрашивал сервис-б; Я использую feign для этого.
Zuul отправляет X-FORWARDED-* заголовки сервисам, чтобы они правильно переписали ссылки HATEOAS (когда сервисы настроены с ForwardedHeaderFilter).
Моя проблема в том, что сервисы общаются друг с другом с помощью Feign, который опирается на Hystrix.
Hystrix создает новый поток для каждого запроса (мы не используем конфигурацию SEMAPHORE), поэтому запрос в Spring RequestContextHolder теряется в запросе Feign от сервис-а до сервис-б, я больше не могу обогатить запрос feign перехватчиком feign, так как исходный запрос потерян.
Переадресация токена авторизации теперь поддерживается непосредственно Spring с параметром hystrix.shareSecurityContext: true
Не существует какой-либо «стандартной» конфигурации, позволяющей Hystrix распределять запросы между потоками.
Решением может быть реализовать свой собственный HystrixConcurrencyStrategy, который является классом из netflix.hystrix.
Моя последняя находка — это Пулл-реквест, который был отправлен в spring-cloud-netflix, но, к сожалению, не интегрирован.
Я могу попытаться скопировать код запроса на извлечение и создать компонент, как написал «eacdy»:
@Bean
public RequestAttributeHystrixConcurrencyStrategy hystrixRequestAutoConfiguration() {
return new RequestAttributeHystrixConcurrencyStrategy();
}
Есть ли более простое решение для пересылки заголовков из Zuul с помощью Hystrix?
Я полагаю, что то, что я пытаюсь сделать, очень стандартно при использовании микросервисов Zuul, Hystrix и HATEOAS, которые взаимодействуют друг с другом, так что, может быть, что-то уже существует (и что я не смог найти)?
Спасибо !





Я думал, что это довольно распространенная вещь, но после долгих исследований я не смог найти способ автоматической пересылки заголовков X-FORWARDED-* с помощью Feign и Hystrix.
Итак, я искал другое решение, которое работает и довольно чисто:
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). В этих файлах также установлен префикс сервис-б.
Эти заголовки добавляются только в том случае, если в файлах свойств установлено свойство «gatewayEnabled».
@Configuration, поэтому поместите ее в пакет «ignorescan» и в своем основном классе загрузки Spring используйте:@ComponentScan(basePackages = { "com.myservice" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.myservice.ignorescan.*"))
В конце будут добавлены заголовки Forward, если для параметра gatewayEnabled установлено значение true, а вызов API к шлюзу получает правильные ссылки HATEOAS.