Hystrix-Integration mit vorhandener Federanwendung

1. Überblick

In link:/Einführung zu Hystrix[letzter Artikel]haben wir uns mit den Grundlagen von Hystrix befasst und wie dies beim Aufbau einer fehlertoleranten und nachgiebigen Anwendung helfen kann.

  • Es gibt viele vorhandene Spring-Anwendungen, die externe Systeme aufrufen, die von Hystrix profitieren würden. ** Leider ist es nicht möglich, diese Anwendungen zur Integration von Hystrix neu zu schreiben, jedoch ist eine nicht-invasive Integration von Hystrix mit möglich die Hilfe von Spring AOP .

In diesem Artikel wird beschrieben, wie Hystrix in eine vorhandene Spring-Anwendung integriert wird.

2. Hystrix in eine Federanwendung

2.1. Bestehende Anwendung

Schauen wir uns den bestehenden Client-Aufrufer der Anwendung an, der den RemoteServiceTestSimulator aufruft, den wir im vorigen Artikel erstellt haben:

@Component("springClient")
public class SpringExistingClient {

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

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

Wie im obigen Codeausschnitt zu sehen ist, ist die Methode invokeRemoteServiceWithOutHystrix für das Aufrufen des Remote-Service RemoteServiceTestSimulator verantwortlich. Natürlich werden Anwendungen in der realen Welt nicht so einfach sein.

2.2. Rundum Hinweis erstellen

Um zu demonstrieren, wie Hystrix integriert wird, verwenden wir diesen Client als Beispiel.

Dazu definieren wir einen Around -Hinweis, der ausgelöst wird, wenn invokeRemoteService ausgeführt wird ** :

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

Der obige Hinweis ist als Around -Hinweis gedacht, der an einem mit @ HystrixCircuitBreaker annotierten Punktschnitt ausgeführt werden soll.

Nun sehen wir uns die Definition der Annotation HystrixCircuitBreaker _ an: _

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

** 2.3. Die Hystrix-Logik

Schauen wir uns jetzt den RemoteServiceCommand an. Es wird als static inner class im Beispielcode implementiert, um die Hystrix-Aufruflogik einzukapseln:

private static class RemoteServiceCommand extends HystrixCommand<String> {

    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);
        }
    }
}

Die gesamte Implementierung der Aspect -Komponente kann hier angezeigt werden.

2.4. Anmerkungen mit @ HystrixCircuitBreaker

Nachdem der Aspekt definiert wurde, können wir unsere Client-Methode mit @ HystrixCircuitBreaker wie folgt kommentieren, und Hystrix wird für jeden Aufruf von kommentierten Methoden provoziert:

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

Der folgende Integrationstest zeigt den Unterschied zwischen der Hystrix-Route und der Nicht-Hystrix-Route.

2.5. Testen Sie die Integration

Zur Veranschaulichung haben wir zwei Methodenausführungsrouten definiert, eine mit Hystrix und eine ohne.

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"));
    }
}

Wenn der Test ausgeführt wird, können Sie sehen, dass der Methodenaufruf ohne Hystrix die gesamte Ausführungszeit des Remote-Service abwartet, während die Hystrix-Route einen Kurzschluss verursacht und die HystrixRuntimeException nach dem definierten Timeout (in unserem Fall 10 Sekunden) auslöst.

3. Schlussfolgerung

Wir können einen Aspekt für jeden Remote-Service-Aufruf erstellen, den wir mit unterschiedlichen Konfigurationen durchführen möchten. Im nächsten Artikel werden wir die Integration von Hystrix vom Beginn eines Projekts aus betrachten.

Den gesamten Code in diesem Artikel finden Sie im Repository GitHub .