我在我的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
下面是实际代码。我用这个玩得更远了。当我在RegistrationHystrix.RegisterSeller()方法中直接调用远程服务时,我看到电路在重复失败时按预期打开。但是,当我将远程服务调用包装在spring重试模板中时,它继续进入回退方法,但电路从未打开。
@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";
}
}
下面是service类,它又调用上面的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一起时没有像预期的那样工作。
您应该在测试时使用Metrics.HealthSnapshot.IntervalinMilliseconds。我猜你是在默认的500毫秒内执行所有3个请求,因此电路没有打开。您可以缩短此间隔,也可以在3个请求之间放置睡眠
。
应用程序可以使用Spring Cloud Netflix项目提供的Hystrix断路器将这个启动器包含在项目pom.xml:spring-cloud-starter-hystrix中。Hystrix不依赖于Netflix Discovery Client。@EnableHystrix注释应放置在配置类(通常是主类)上。那么方法可以用@HystrixCommand注释来被断路器保护。有关详细信息,请
Hystrix的主要优点之一是它收集关于每个HystrixCommand的一套指标。Hystrix仪表板以有效的方式显示每个断路器的运行状况。 图3. Hystrix仪表板
Netflix的创造了一个调用的库Hystrix实现了断路器图案。在微服务架构中,通常有多层服务调用。 图1.微服务图 较低级别的服务中的服务故障可能导致用户级联故障。当对特定服务的呼叫达到一定阈值时(Hystrix中的默认值为5秒内的20次故障),电路打开,不进行通话。在错误和开路的情况下,开发人员可以提供后备。 图2. Hystrix回退防止级联故障 开放式电路会停止级联故障,并允许不必要的或
我正在尝试春云和春靴。它使用了Netflix的OSS应用程序,其中有Ribbon和Hystrix。 Ribbon是一个负载均衡器,带有一些功能,其中一个是断路器。
有一种显而易见的方法可以将业务异常包装到holder对象中,从run()方法返回它,然后将其解包装回异常并重新抛出。但它想知道是否有更干净的方法。
或者如果在我的应用程序上下文中根本不可能验证这一点? 任何输入都是有价值的。