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 .