Hystrix断路器无法断开电路

时间:2020-07-08 20:21:49

标签: hystrix circuit-breaker

我正在Spring Boot应用程序中使用Hystrix实现断路器,我的代码如下:

@service
public class MyServiceHandler {

    @HystrixCommand(fallbackMethod="fallback")
    
    public String callService() {
       // if(remote service is not reachable
       // throw ServiceException
    }
    
    public String fallback() {
       // return default response
    }
}

// In application.properties, I have below properties defined:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
hystrix.command.default.circuitBreaker.requestVolumeThreshold=3
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=30000
hystrix.threadpool.default.coreSize=4
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds=200000

我看到在callService()每次失败时都调用fallback()。但是,3次失败后,电路无法打开。 3次失败后,我期望它会直接调用fallback()并跳过callService()。但是,这没有发生。有人可以告诉我我在做什么错吗?

谢谢, 贾根(B Jagan)

7月26日编辑,在下面添加了更多详细信息:

下面是实际的代码。我在这方面玩得更远。当我直接在RegistrationHystrix.registerSeller()方法中调用远程服务时,我看到电路在重复失败时按预期方式打开。但是,当我将远程服务调用包装在Spring retry模板中时,它将继续进入回退方法,但是电路永远不会打开。

@Service
public class RegistrationHystrix {
    Logger logger = LoggerFactory.getLogger(RegistrationHystrix.class);
    private RestTemplate restTemplate;
    private RetryTemplate retryTemplate;

    public RegistrationHystrix(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
        retryTemplate = new RetryTemplate();
        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(1000l);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3);
        retryTemplate.setRetryPolicy(retryPolicy);
    }

    @HystrixCommand(fallbackMethod = "fallbackForRegisterSeller", commandKey = "ordermanagement")
    public String registerSeller(SellerDto sellerDto)  throws Exception {
        String response = retryTemplate.execute(new RetryCallback<String, Exception>() {
                   @Override
                   public String doWithRetry(RetryContext context) {
                           logger.info(String.format("Retry count %d", context.getRetryCount()));
                          return restTemplate.postForObject("/addSeller", sellerDto, String.class);
                   }
       });
       return response;
    }

    public List<SellerDto> getSellersList() {
        return restTemplate.getForObject("/sellersList", List.class);
    }

    public String fallbackForRegisterSeller(SellerDto sellerDto, Throwable t) {
        logger.error("Inside fall back, cause - {}", t.toString());
        return "Inside fallback method. Some error occured while calling service for seller registration";
    }
}

下面是服务类,它依次调用上述Hystrix包装的服务。此类又由控制器调用。

@Service
public class RegistrationServiceImpl implements RegistrationService {

    Logger logger = LoggerFactory.getLogger(RegistrationServiceImpl.class);
    private RegistrationHystrix registrationHystrix;


    public RegistrationServiceImpl(RegistrationHystrix registrationHystrix) {
        this.registrationHystrix = registrationHystrix;
    }

    @Override
    public String registerSeller(SellerDto sellerDto)  throws Exception {
        long start = System.currentTimeMillis();
        String registerSeller = registrationHystrix.registerSeller(sellerDto);
        logger.info("add seller call returned in - {}", System.currentTimeMillis() - start);
        return registerSeller;

    }

因此,我试图了解为什么将断路器与Spring RetryTemplate一起使用时无法按预期工作。

1 个答案:

答案 0 :(得分:0)

您应该在测试时使用metrics.healthSnapshot.intervalInMilliseconds。我猜您正在默认500毫秒内执行所有3个请求,因此电路无法打开。您可以缩短此间隔,也可以在3个请求之间放置一个sleep