N способов играть в конфигурацию тайм-аута Hystrix

Spring Cloud

Некоторое время назад на моей планете знаний друг спросил меня, как заставить Hystrix поддерживать настройку тайм-аута на уровне интерфейса.Сегодня я напишу статью, чтобы популяризировать несколько способов настройки тайм-аута в Hystrix.

Что касается того, будете ли вы использовать Ali Sentinel или Netflix Hystrix в будущем, мне все равно, но сегодняшняя тема по-прежнему Netflix Hystrix, по крайней мере, их все еще много, поэтому давайте сегодня рассмотрим эту статью.

@HystrixCommand

Если мы используем аннотацию @HystrixCommand, мы можем указать время ожидания непосредственно в аннотации следующим образом:

@HystrixCommand(fallbackMethod="fallback",
	commandProperties = {
	     @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000" )
	}
)

Конечно, вы также можете указать commandKey, а затем настроить время ожидания в файле конфигурации следующим образом:

@HystrixCommand(fallbackMethod="fallback",commandKey="userGetKey")

Файл конфигурации настраивает период ожидания для commandKey:

hystrix.command.userGetKey.execution.isolation.thread.timeoutInMilliseconds = 13000

Глобальная конфигурация

Если вы просто хотите настроить его глобально, вы можете настроить тайм-аут по умолчанию:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000

Конфигурация уровня интерфейса

Предположим, что наш Feign Client определен следующим образом:

@FeignClient(value = "user-service", fallbackFactory = UserRemoteClientFallbackFactory.class)
public interface UserRemoteClient {
	
	@GetMapping("/user/get")
	public ResponseData<UserDto> getUser(@RequestParam("id") Long id);
	
}

Тогда конфигурация следующая:

hystrix.command.UserRemoteClient#getUser(Long).execution.isolation.thread.timeoutInMilliseconds = 300

Зачем настраивать его вышеописанным способом?

По сути, это настройка commandKey. Зная правила генерации commandKey, мы можем настроить уровень интерфейса. Правила уровня интерфейса: имя клиента#имя метода (тип параметра)

Исходный код находится в feign.hystrix.SetterFactory.Default:

String commandKey = Feign.configKey(target.type(), method);

Конфигурация уровня обслуживания

1. Для уровня обслуживания в Zuul напрямую настройте идентификатор обслуживания следующим образом:
hystrix.command.service-id.execution.isolation.thread.timeoutInMilliseconds=3000

Причина, по которой идентификатор службы настроен в Zuul, заключается в том, что commandKey является используемым идентификатором службы, что можно сделать с помощью анализа исходного кода.

Первое, что нужно ввести, — это метод run в RibbonRoutingFilter, а затем мы рассмотрим основной метод пересылки:

ClientHttpResponse response = forward(commandContext);

В форварде есть следующий код:

RibbonCommand command = this.ribbonCommandFactory.create(context);

Конкретную реализацию можно найти с помощью create. Здесь это зависит от того, какой HTTP-клиент вы используете. По умолчанию существует три реализации. Расположение по умолчанию — org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory.create( Метод RibbonCommandContext ).

Основное внимание уделяется новой строке кода HttpClientRibbonCommand. Первым параметром является serviceId. Давайте посмотрим на полные параметры конструктора HttpClientRibbonCommand:

Таким образом, идентификатор службы — это commandKey.

2. Для уровня службы в Feign вам необходимо настроить commandKey, вы можете использовать идентификатор службы или имя клиента Feign следующим образом:
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.hystrix.enabled")
public Feign.Builder feignHystrixBuilder() {
	return HystrixFeign.builder().setterFactory(new SetterFactory() {

		@Override
		public Setter create(Target<?> target, Method method) {
			String groupKey = target.name();
			String commandKey = Feign.configKey(target.type(), method);
			return HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
						//.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
						//.andCommandKey(HystrixCommandKey.Factory.asKey(groupKey))
						.andCommandKey(HystrixCommandKey.Factory.asKey(target.type().getSimpleName()));
			}
	});
}
  • .andCommandKey(HystrixCommandKey.Factory.asKey(commandKey)) интерфейс по умолчанию

  • .andCommandKey(HystrixCommandKey.Factory.asKey(groupKey)) метод идентификатора службы

  • .andCommandKey(HystrixCommandKey.Factory.asKey(target.type().getSimpleName())); Метод фиктивного имени клиента

Если вы настроите его, вы можете заполнить недоступный commandKey в соответствии с различными конфигурациями:

hystrix.command.Feign Client Name.execution.isolation.thread.timeoutInMilliseconds=3000

Оставьте вопрос для всех, чтобы подумать, добро пожаловать, чтобы оставить сообщение для обсуждения:

Если мы настраиваем commandKey, это означает, что при использовании вызова Feign может поддерживаться только одна конфигурация тайм-аута, либо уровень интерфейса по умолчанию, либо пользовательский уровень обслуживания. Так есть ли способ поддерживать оба одновременно?

猿天地