[JAVA] Wiederholen Sie mit Feign (OpenFeign)

Im vorherigen Artikel (https://qiita.com/totto357/items/90f9276697edec08a4ba) habe ich vorgestellt, wie ein HTTP-Client nur mit Anmerkungen erstellt wird. Im eigentlichen HTTP-Client muss es jedoch erneut versucht werden. es gibt. Tatsächlich kann es viele Projekte geben, die eine HTTP-Client-Klasse mit "RestTemplate" erstellen und dort eine Wiederholungsverarbeitung durchführen.

Lassen Sie uns diesen Wiederholungsprozess mit "OpenFeign" realisieren.

Wie es funktioniert

Der Wiederholungsprozess von "OpenFeign" kann durch Implementierung von zwei Schnittstellen realisiert werden.

ErrorDecoder

ErrorDecoder ist eine Schnittstelle zum Entscheiden, welche Art von Ausnahme ausgelöst wird, wenn eine andere Antwort als die 200er in einer HTTP-Anforderung zurückgegeben wird.

Als Beispiel implementieren wir eine Klasse, die "IllegalArgumentException" zurückgibt, wenn sie "400" ist.

class IllegalArgumentExceptionOn404Decoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() == 400) {
            throw new IllegalArgumentException("Es ist 400.");
        }
        return new ErrorDecoder.Default().decode(methodKey, response);
    }
}

Grundsätzlich denke ich, dass Sie das Verhalten ändern können, indem Sie sich response.status () ansehen. Wenn Sie RetryableException in decode werfen, wird der folgendeRetryer.continueOrPropagateWird gerufen.

Retryer

Retryer wird aufgerufen, wenn RetryableException ausgelöst wird, und ist eine Schnittstelle zum Verwalten des Wiederholungsintervalls und der Häufigkeit.

Der Standard-Retryer ist Retryer.Default und wird 5 Mal in 100 ms versucht Es soll gemacht werden.

Wenn Sie nur das Wiederholungsintervall und die Häufigkeit ändern möchten, ist "Retryer.Default" meiner Meinung nach ausreichend.

Wie benutzt man

Geben Sie die Ausführungsklasse der beiden oben genannten Schnittstellen in application.yml an.

feign:
  client:
    config:
      {{yourFeignName}}:
        errorDecode: com.example.feign.MyErrorDecoder
        retryer: com.example.feign.MyRetryer

Setzen Sie "yourFeignName" auf den in "FeignClient.name" angegebenen Wert. Wenn Sie "FeignClient.name" trennen, können Sie den Wiederholungsprozess für jeden "Namen" trennen.

Stichprobe

Fügen wir dem vorherigen [Wetterbeispiel] einen Wiederholungsprozess hinzu (https://github.com/totto357/open-feign-client-example).

MyErrorDecoder.java In diesem Beispiel wird versucht, es erneut zu versuchen, wenn "503" und "504".

package com.example.ofc.feign;

import org.springframework.web.client.RestClientException;

import feign.Response;
import feign.RetryableException;
import feign.codec.ErrorDecoder;

public class MyErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        RestClientException cause = new RestClientException(response.toString());

        final int status = response.status();
        if (status == 503 || status == 504) {
            return new RetryableException(methodKey, cause, null);
        }

        return cause;
    }

}

MyRetryer.java Ich habe gerade Retryer.Default ein wenig geändert.

package com.example.ofc.feign;

import static java.util.concurrent.TimeUnit.SECONDS;

import feign.RetryableException;
import feign.Retryer;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyRetryer implements Retryer {

    private final int maxAttempts;
    private final long period;
    private final long maxPeriod;
    int attempt;
    long sleptForMillis;

    public MyRetryer() {
        this(100, SECONDS.toMillis(1), 3);
    }

    public MyRetryer(long period, long maxPeriod, int maxAttempts) {
        this.period = period;
        this.maxPeriod = maxPeriod;
        this.maxAttempts = maxAttempts;
        this.attempt = 1;
    }

    // visible for testing;
    protected long currentTimeMillis() {
        return System.currentTimeMillis();
    }

    @Override
    public void continueOrPropagate(RetryableException e) {
        log.info("Wiederholen Sie die Verarbeitung");
        if (attempt++ >= maxAttempts) {
            throw e;
        }

        long interval;
        if (e.retryAfter() != null) {
            interval = e.retryAfter().getTime() - currentTimeMillis();
            if (interval > maxPeriod) {
                interval = maxPeriod;
            }
            if (interval < 0) {
                return;
            }
        } else {
            interval = nextMaxInterval();
        }
        try {
            Thread.sleep(interval);
        } catch (InterruptedException ignored) {
            Thread.currentThread().interrupt();
            throw e;
        }
        sleptForMillis += interval;
    }

    /**
     * Calculates the time interval to a retry attempt. <br>
     * The interval increases exponentially
     * with each attempt, at a rate of nextInterval *= 1.5 (where 1.5 is the
     * backoff factor), to the
     * maximum interval.
     *
     * @return time in nanoseconds from now until the next attempt.
     */
    long nextMaxInterval() {
        long interval = (long) (period * Math.pow(1.5, attempt - 1));
        return interval > maxPeriod ? maxPeriod : interval;
    }

    @Override
    public Retryer clone() {
        return new MyRetryer(period, maxPeriod, maxAttempts);
    }
}

application.yml Geben Sie die beiden oben genannten Implementierungsklassen an.

server:
  port: 8088
  application:
    name: open-feign-client

feign:
  client:
    config:
      weather:
        errorDecoder: com.example.ofc.feign.MyErrorDecoder
        retryer: com.example.ofc.feign.MyRetryer

Zusammenfassung

Ich habe versucht, die Wiederholungsverarbeitung mit "OpenFeign" zu realisieren. Es scheint einfach zu reparieren zu sein, da es realisiert werden kann, ohne den API-Client selbst zu berühren.

Klicken Sie hier für dieses Beispiel https://github.com/totto357/open-feign-client-example

Recommended Posts

Wiederholen Sie mit Feign (OpenFeign)
Implementieren Sie den API-Client mit nur Anmerkungen unter Verwendung von Feign (OpenFeign).
So erreichen Sie den Dateidownload mit Feign
So erreichen Sie das Hochladen von Dateien mit Feign