Рубрики
Без рубрики

Интеграция Hystrix с существующим приложением Spring

В этой статье мы рассмотрим, как интегрировать Hystrix в существующее приложение Spring с помощью Spring AOP.

Автор оригинала: baeldung.

1. Обзор

В предыдущей статье мы рассмотрели основы Hystrix и то, как она может помочь в создании отказоустойчивого и устойчивого приложения.

Существует множество существующих приложений Spring, которые делают вызовы внешним системам, которые выиграли бы от Hystrix. К сожалению, может оказаться невозможным переписать эти приложения для интеграции Hystrix, однако неинвазивный способ интеграции Hystrix возможен с помощью Spring AOP .

В этой статье мы рассмотрим, как интегрировать Hystrix с существующим приложением Spring.

2. Hystrix в весеннее приложение

2.1. Существующее приложение

Давайте взглянем на существующий клиентский абонент приложения, который вызывает Симулятор тестирования удаленных служб , который мы создали в предыдущей статье:

@Component("springClient")
public class SpringExistingClient {

    @Value("${remoteservice.timeout}")
    private int remoteServiceDelay;

    public String invokeRemoteServiceWithOutHystrix() throws InterruptedException {
        return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
    }
}

Как мы можем видеть в приведенном выше фрагменте кода, метод invoke Remote Service без Hystrix отвечает за вызовы RemoteServiceTestSimulator remote service. Конечно, в реальном мире приложения не будут такими простыми.

2.2. Создайте вокруг Совета

Чтобы продемонстрировать, как интегрировать Hystrix, мы собираемся использовать этот клиент в качестве примера.

Для этого мы определим Вокруг совет, который сработает, когда вызовет удаленную службу будет выполнен :

@Around("@annotation(com.baeldung.hystrix.HystrixCircuitBreaker)")
public Object circuitBreakerAround(ProceedingJoinPoint aJoinPoint) {
    return new RemoteServiceCommand(config, aJoinPoint).execute();
}

Вышеприведенный совет разработан как Around совет, который должен выполняться в точке с аннотацией @Hystrix circuitBreaker .

Теперь давайте посмотрим на определение автоматического выключателя Hystrix аннотацию :

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HystrixCircuitBreaker {}

2.3. Логика Истрикса

Теперь давайте взглянем на команду Remote Service . Он реализован как статический внутренний класс в примере кода, чтобы инкапсулировать логику вызова Hystrix:

private static class RemoteServiceCommand extends HystrixCommand {

    private ProceedingJoinPoint joinPoint;

    RemoteServiceCommand(Setter config, ProceedingJoinPoint joinPoint) {
        super(config);
        this.joinPoint = joinPoint;
    }

    @Override
    protected String run() throws Exception {
        try {
            return (String) joinPoint.proceed();
        } catch (Throwable th) {
            throw new Exception(th);
        }
    }
}

Всю реализацию Аспекта компонента можно увидеть здесь .

2.4. Аннотировать С Помощью @HystrixCircuitBreaker

Как только аспект будет определен, мы можем аннотировать наш клиентский метод с помощью @Hystrix circuitBreaker , как показано ниже, и Hystrix будет вызываться для каждого вызова аннотированных методов:

@HystrixCircuitBreaker
public String invokeRemoteServiceWithHystrix() throws InterruptedException{
    return new RemoteServiceTestSimulator(remoteServiceDelay).execute();
}

Приведенный ниже интеграционный тест продемонстрирует разницу между маршрутом Hystrix и маршрутом без Hystrix.

2.5. Протестируйте интеграцию

Для демонстрации мы определили два маршрута выполнения метода, один с Hystrix, а другой без.

public class SpringAndHystrixIntegrationTest {

    @Autowired
    private HystrixController hystrixController;

    @Test(expected = HystrixRuntimeException.class)
    public void givenTimeOutOf15000_whenClientCalledWithHystrix_thenExpectHystrixRuntimeException()
      throws InterruptedException {
        hystrixController.withHystrix();
    }

    @Test
    public void givenTimeOutOf15000_whenClientCalledWithOutHystrix_thenExpectSuccess()
      throws InterruptedException {
        assertThat(hystrixController.withOutHystrix(), equalTo("Success"));
    }
}

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

3. Заключение

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

Весь код в этой статье можно найти в репозитории GitHub .