簡體   English   中英

Feign:根據響應狀態重試

[英]Feign: Retry depending on response status

我目前正在使用 Spring Cloud 和 Feign 在我的應用程序中使用微服務。 由於它可能發生,數據庫連接等在單個服務實例中失敗,使其返回 500 HTTP 狀態代碼,我想確保下一個服務器由服務的客戶端重試。 目前,當服務根本沒有運行時,Ribbon 的重試機制就像一個魅力一樣,但是當它收到 500 狀態代碼時,它仍然立即返回一個錯誤,沒有任何重試。

如果實例返回 500 響應,是否可以配置 Feign 客戶端或其底層 Ribbon 負載均衡器以重試下一個服務器?

配置與此線程中的配置幾乎相同: Feign 重試是否需要某種配置?

我很想使用像 Ribbons 的 HttpResponseValidator ( https://github.com/Netflix/ribbon/blob/master/ribbon/src/main/java/com/netflix/ribbon/http/HttpResponseValidator.java ) 這樣的實現,但是我找不到任何可用於 Spring Cloud 及其 Feign/Ribbon 集成的東西

這個問題很老,解決方案可能已經找到或當時無法解決。 無論如何,我認為答案仍然可以幫助某人8)。 請以此為參考,此代碼不適用於生產。 Feign允許您配置errorDecoder-這是發生魔術的地方。

Feign.Builder builder = Feign.builder()
  .errorDecoder(new RetryOnScaleErrorDecoder())

這是實現,我使用該類在服務擴展時從AWS獲取的HTTP錯誤429重試請求

public static class RetryOnScaleErrorDecoder implements ErrorDecoder {

  @Override
  public Exception decode(String methodKey, Response response) {
    FeignException exception = errorStatus(methodKey, response);
    // This is a terrible part please check how feign.codec.ErrorDecoder.RetryAfterDecoder is implemented for proper parsing of retry-after header
    Collection<String> headers = response.headers().get("Retry-After");

    String repeatAfterString = "0";
    if (Objects.nonNull(headers)) {
      repeatAfterString = Iterables.getFirst(headers, "0");
    }

    assert repeatAfterString != null;

    Date repeatAfter = new Date(currentTimeMillis());

    if (repeatAfterString.matches("^[0-9]+$")) {
      try {
        long deltaMillis = SECONDS.toMillis(Long.parseLong(repeatAfterString));
        repeatAfter = new Date(currentTimeMillis() + deltaMillis);
      } catch (NumberFormatException ignored) {
        // TODO: logging
      }
    }
    // That's the part where we decide to retry based on status code value
    if (exception.status() == 429) {
      return new RetryableException(
          response.status(),
          exception.getMessage(),
          response.request().httpMethod(),
          exception,
          repeatAfter
      );
    }
    return exception;
  }
}

我認為與Ribbon結合使用將產生預期的結果。

試試這個配置:MY-SPRING-API.ribbon.retryableStatusCodes=404,500

這是同一個問題: Feign client and Spring retry

文件是: https : //docs.spring.io/spring-cloud-netflix/docs/2.2.10.RELEASE/reference/html/#retrying-failed-requests

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM