当前位置: 首页 > 知识库问答 >
问题:

假:根据响应状态重试

詹唯
2023-03-14

我目前正在使用Spring Cloud和Feign在我的应用程序中使用微服务。由于在单个服务实例中数据库连接或类似的情况可能会失败,使其返回500个HTTP状态代码,所以我想确保下一个服务器是由服务的客户机重试的。目前,Ribbon的重试机制在服务完全不运行时就像一个魅力一样工作,但当它收到500状态码时,它仍然会立即返回错误,而不进行任何重试。

如果一个实例返回500响应,是否可以配置假客户机或它们的底层功能区负载均衡器来重试下一个服务器?

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

共有1个答案

李泓
2023-03-14

这个问题很古老,当时可能已经找到了解决办法,或者是不可能的。不管怎样,我认为这个答案可能仍然对某人有帮助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;
  }
}

我认为,与丝带配合,会产生预期的效果。

 类似资料:
  • 在检查完成之前,我是否必须在包装器中捕获一些东西以防止响应发送到客户机?

  • 我正在使用react在我的网站中切换明暗模式。我还希望主题使用localstorage持久化。问题是,当单击switch切换主题时,相应的localstorage主题值不会更新。我知道状态更新是异步的,但我想解决这个问题。 我的代码: 我尝试使用async await,但结果是一样的。

  • 问题内容: 我有一个API调用,我需要对其进行一些检查并可能返回各种状态代码。我不需要自定义视图或任何东西,我只需要返回正确的代码。如果用户未通过适当的凭据,则需要返回401状态。如果他们尚未发送受支持的请求格式,则需要返回400状态。 因为它是一个API,所以我真正想做的就是设置响应状态并以一条简单的愚蠢消息退出,该消息说明请求失败的原因(可能使用)。刚好足以完成工作,但我还无法使其正常工作。我

  • 我用的是和Gradle的协议。是否可以从状态更改URL捕获响应?例如,我正在向数据库中添加一条新记录。提供程序创建一个唯一的id,该id必须用于该记录的其他操作。

  • HTTP响应消息的响应状态行分为三部分:HTTP版本、状态码和状态信息,如下所示: HTTP/1.1 200 OK 其中HTTP版本可以是HTTP/1.1或HTTP/1.0,这由Web服务器所支持的HTTP版本决定。状态信息的内容和状态相关,如404状态码所对应的HTTP1.1规范中的状态信息是Not Found。由于HTTP版本一般是基本固定的,而状态信息是随着状态码的变化而变的。因此,在HTT

  • 我正在使用Twilio WhatsApp API。我有沙盒账户,我可以从Twilio向WhatsApp号码发送消息,但是,我面临一个问题,当消息不发送给收件人时,我从API获得的状态与我获得的成功相同。 如果需要,这里是我的代码。