首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Feign:根据响应状态重试

Feign:根据响应状态重试
EN

Stack Overflow用户
提问于 2016-06-03 20:17:31
回答 2查看 5.6K关注 0票数 5

我目前正在使用Spring Cloud和Feign在我的应用程序中使用微服务。由于数据库连接或类似情况在单个服务实例中可能会失败,使其返回500 HTTP状态码,因此我希望确保服务的客户端重试下一台服务器。目前,Ribbon的重试机制在服务根本没有运行时就像一个护身符一样工作,但是当它收到500状态代码时,它仍然会立即返回一个错误,而不需要任何重试。

是否可以配置Feign客户端或其底层Ribbon负载均衡器,以便在实例返回500响应时重试下一个服务器?

该配置与此线程中的配置基本相同:Does Feign retry require some sort of configuration?

我很想使用像Ribbons的HttpResponseValidator (https://github.com/Netflix/ribbon/blob/master/ribbon/src/main/java/com/netflix/ribbon/http/HttpResponseValidator.java)这样的实现,但我找不到任何可用于Spring Cloud及其Feign/Ribbon集成的实现

EN

回答 2

Stack Overflow用户

发布于 2019-05-09 06:32:42

这个问题由来已久,解决方案可能已经找到,或者当时不可能。不管怎么说,我认为这个答案可能对某些人还是有帮助的。请将此代码作为参考,此代码不适用于生产。Feign允许你配置errorDecoder --这是魔术发生的地方。

代码语言:javascript
复制
Feign.Builder builder = Feign.builder()
  .errorDecoder(new RetryOnScaleErrorDecoder())

下面是实现,当服务扩展时,我使用这个类来重试从AWS得到的HTTP错误429的请求

代码语言:javascript
复制
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一起使用将会产生预期的结果。

票数 2
EN

Stack Overflow用户

发布于 2022-01-06 17:04:53

尝试此配置: 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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37614202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档