1

我知道我们可以recordExceptions()在构建时使用CircuitBreakerConfig它来注册断路器应转换为OPEN状态的异常。

代码

resilience4j-feign用来装饰我的CircuitBreaker. 如果您能指出我的代码示例,那将非常有帮助。

问题

如果出现特定的 HTTP 状态代码(例如,在503 Service Unavailable上) ,如何使断路器启动?

4

3 回答 3

2

从文档中,创建和配置 CircuitBreaker

// Create a custom configuration for a CircuitBreaker
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
  .recordExceptions(IOException.class, TimeoutException.class) // add you exceptions here!!!
  .ignoreExceptions(BusinessException.class, OtherBusinessException.class)
  .build();

记录为失败并因此增加失败率的异常列表。任何匹配或从列表之一继承的异常都算作失败,除非通过 ignoreExceptions 明确忽略。

于 2020-03-26T07:56:27.620 回答
1

您需要为客户端的外部调用编写异常/响应处理程序,并根据收到的 http 状态引发自定义异常。然后将这些异常注册为断路器配置中的记录异常。下面是一个小例子。CB 将仅在 AbcException 上打开。CB配置是resilience4j.circuitbreaker.instances.bookService.record-exceptions=com.sk.example.cb.circuitbreakerr4j.AbcException

@Service
@Slf4j
public class BookApiService {
  RestTemplate restTemplate = new RestTemplate();
  @CircuitBreaker(name = "bookService", fallbackMethod = "getBookFallback")
  public String getBook(){
    try {
      ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(new URI("http://localhost:8080/book"), String.class);
      if(null != stringResponseEntity){
        if(stringResponseEntity.getStatusCode().is2xxSuccessful()){
          return stringResponseEntity.getBody();
        }
      }
    } catch (URISyntaxException e) {
      e.printStackTrace();
    }catch (HttpServerErrorException e){
      log.error("Service unavailable",e);
      if(e.getMessage().startsWith("503")) {
        throw new AbcException();
      }else{
        throw e;
      }
    }
    return "";
  }

于 2020-04-01T01:22:01.967 回答
0

TL;DR:使用自定义异常将 HTTP 状态(例如 503)从 HTTP 客户端(例如 Feign)传送到 Resilience4J

  1. Feign:实现和配置一个在 HTTP 状态上ErrorDecoder 抛出自定义异常,如 503
  2. Resilience4J:使用断路器配置记录该自定义异常。

假装

Feign 默认抛出一个FeignException错误的 HTTP 状态码。您可以通过方法int status()获取状态代码编号。

要自定义您的 feign-clients 错误处理,请配置(自定义)实现ErrorDecoder

如果您需要对处理意外响应进行更多控制,Feign 实例可以ErrorDecoder通过构建器注册自定义。[..] 导致 HTTP 状态不在 2xx 范围内的所有响应都将触发ErrorDecoder's decode 方法,允许您处理响应、将失败包装到自定义异常或执行任何其他处理。如果您想再次重试请求,请抛出RetryableException. 这将调用注册的Retryer.

自定义 Feign 错误处理

实现并配置自定义ErrorDecoder以在 HTTP 状态 503 的情况下引发异常。

@Component
@Slf4j
public class CustomErrorDecoder implements ErrorDecoder {
    
    @Override
    public Exception decode(String methodKey, Response response) {
        
        switch (response.status()) {
            case 400:
                log.error("Status code {} on methodKey '{}'", response.status(), methodKey);
            case 503:
                return new ServiceUnavailableException("HTTP status 503 when calling " methodKey);
            default:
                return new Exception(response.reason());
        } 
    }
    
}

这将抛出您的自定义异常ServiceUnavailableException

Resilienc4J 的断路器

默认情况下,断路器对异常做出反应。它会记录它们,如果在太短的时间内太多,它会打开电路。

您可以在业务级别上按预期配置要记录哪些异常以及忽略哪些异常。

在特定异常上触发断路器

您可以配置 CiruitBreaker 来记录该异常笑话的答案解释了如何做到这一点。

也可以看看

于 2022-01-09T13:00:14.907 回答