it-swarm.com.de

Rufen Sie eine Fehlerausnahme in der @HystrixCommand-Fallback-Methode ab

Gibt es eine Möglichkeit, den Grund zu ermitteln, aus dem eine HystrixCommand fehlgeschlagen ist, wenn die @HystrixCommand-Annotation in einer Spring Boot-Anwendung verwendet wird? Es sieht so aus, als hätten Sie, wenn Sie Ihre eigene HystrixCommand implementieren, Zugriff auf die getFailedExecutionException, aber wie können Sie darauf zugreifen, wenn Sie die Annotation verwenden? Ich möchte in der Fallback-Methode je nach Art der aufgetretenen Ausnahme unterschiedliche Aktionen ausführen können. Ist das möglich?

Ich habe ein note about HystrixRequestContext.initializeContext() gesehen, aber die HystrixRequestContext gibt Ihnen keinen Zugriff auf irgendetwas. Gibt es eine andere Möglichkeit, diesen Kontext zu verwenden, um Zugriff auf die Ausnahmen zu erhalten?

12
Andrew Serff

Ich habe auch keine Möglichkeit gefunden, die Ausnahme mit Annotationen zu erhalten, aber das Erstellen meines eigenen Befehls hat für mich wie folgt funktioniert:

public static class DemoCommand extends HystrixCommand<String> {

    protected DemoCommand() {
        super(HystrixCommandGroupKey.Factory.asKey("Demo"));
    }

    @Override
    protected String run() throws Exception {
        throw new RuntimeException("failed!");
    }

    @Override
    protected String getFallback() {
        System.out.println("Events (so far) in Fallback: " + getExecutionEvents());
        return getFailedExecutionException().getMessage();
    }

}

Hoffentlich hilft das auch jemand anderem. 

11
Andrew Serff

Fügen Sie einfach einen Throwable-Parameter zur Fallback-Methode hinzu, und es wird die Ausnahme empfangen, die der ursprüngliche Befehl erzeugt hat.

Von https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica

    @HystrixCommand(fallbackMethod = "fallback1")
    User getUserById(String id) {
        throw new RuntimeException("getUserById command failed");
    }

    @HystrixCommand(fallbackMethod = "fallback2")
    User fallback1(String id, Throwable e) {
        assert "getUserById command failed".equals(e.getMessage());
        throw new RuntimeException("fallback1 failed");
    }
40
MattJ

Ich habe keine Möglichkeit gefunden, die Ausnahme mit den Anmerkungen zu erhalten, aber ich habe HystrixPlugins gefunden, mit der Sie eine HystrixCommandExecutionHook registrieren können. 

HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixCommandExecutionHook() {
            @Override
            public <T> void onFallbackStart(final HystrixInvokable<T> commandInstance) {

            }
        });

Die Befehlsinstanz ist eine GenericCommand.

2
Ákos Ratku

Wie in der Dokumentation angegeben, wird die Methode Hystrix-DokumentationgetFallback() ausgelöst, wenn

  1. Immer, wenn eine Befehlsausführung fehlschlägt: Wenn eine Ausnahme von construct () oder run () ausgelöst wird 
  2. Wenn der Befehl kurzgeschlossen ist, weil der Stromkreis offen ist 
  3. Wenn der Threadpool und die Warteschlange oder der Semaphor des Befehls ausgelastet sind 
  4. Wenn der Befehl seine Timeout-Länge überschritten hat.

So können Sie leicht herausfinden, was Ihre aufgerufene Fallback-Methode ausgelöst hat, indem Sie die Ausführungsausnahme einem Throwable-Objekt zuweisen.

Angenommen, Ihr HystrixCommand gibt einen String zurück

public class ExampleTask extends HystrixCommand<String> {
   //Your class body
}

wie folgt vorgehen:

@Override
    protected ErrorCodes getFallback() {
        Throwable t = getExecutionException();
        if (circuitBreaker.isOpen()) {
            // Log or something
        } else if (t instanceof RejectedExecutionException) {
            // Log and get the threadpool name, could be useful
        } else {
            // Maybe something else happened
        }
        return "A default String"; // Avoid using any HTTP request or ypu will need to wrap it also in HystrixCommand
    }

Mehr Infos hier

1
vicco

Meistens habe ich nur getFailedExecutionException () verwendet. 

   Exception errorFromThrowable = getExceptionFromThrowable(getExecutionException());
   String errMessage = (errorFromThrowable != null) ? errorFromThrowable.getMessage()

das gibt mir immer bessere Ergebnisse.

1