1、 Hystrix
Netflix has created a library called Hystrix that implements the circuit breaker pattern. In a microservice architecture it is common to have multiple layers of service calls.
官网:Netflix已经创建了一个名为Hystrix的库来实现断路器模式。在微服务中,通常有多层服务调用。
官网中的意思,我想已经翻译的很明白了,Hystrix就是来实现断路器模式的一个实现库。
A service failure in the lower level of services can cause cascading failure all the way up to the user. When calls to a particular service reach a certain threshold (20 failures in 5 seconds is the default in Hystrix), the circuit opens and the call is not made. In cases of error and an open circuit a fallback can be provided by the developer.
翻译:较低层服务如果出现故障,就可能导致用户级联故障。当对特定的服务请求到达阀值时,断路器会开启,请求不可用。。。。。
哎,英文底子差,有些翻译不明白。简单来说吧,就是在所请求的服务出现问题导致请求失败时,那么Hystrix就不会在去调用这个请求了,而直接调用所配置的fallback方法。
2、 怎么样使用Hystrix
按照惯例,要使用一个东西,就要先在pom.xml文件中引入相关的starter。下面引入Hystrix的依赖包:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
官网API中给了我们如下例子:
Example boot app:
@SpringBootApplication
@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
@Component
public class StoreIntegration {
@HystrixCommand(fallbackMethod = "defaultStores")
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}
public Object defaultStores(Map<String, Object> parameters) {
return /* something useful */;
}
}
需要的配置:
1) 在Application类要配置@EnableCircuitBreaker 以开启断路器的使用;
2) 在要访问的接口中,配置 @HystrixCommand,并配置fallbackMethod的方法;
3) 所配置的fallbackMethod方法,需要定义。
完成如上步骤,我们就可以测试这个实例了,并在浏览器中方法,当停掉所需要请求的微服务时,由Hystrix为我们直接调用fallback方法。
3、 Hystrix Health Indicator及Metrics Stream
Health Indicator
The state of the connected circuit breakers are also exposed in the /health endpoint of the calling application.
{
"hystrix": {
"openCircuitBreakers": [
"StoreIntegration::getStoresByLocationLink"
],
"status": "CIRCUIT_OPEN"
},
"status": "UP"
}
Hystrix Metrics Stream
To enable the Hystrix metrics stream include a dependency on spring-boot-starter-actuator. This will expose the/hystrix.stream as a management endpoint.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId></dependency>
4、 Feign对Hystrix的支持
If Hystrix is on the classpath, by default Feign will wrap all methods with a circuit breaker. Returning a com.netflix.hystrix.HystrixCommand is also available. This lets you use reactive patterns (with a call to.toObservable() or .observe() or asynchronous use (with a call to .queue()).
To disable Hystrix support for Feign, set feign.hystrix.enabled=false.
To disable Hystrix support on a per-client basis create a vanilla Feign.Builder with the “prototype” scope, e.g.:
@Configuration
public class FooConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
译:如果Hystrix在类路径上,默认情况下,Feign将使用断路器包装所有方法。返回com.netflix.hystrix.HystrixCommand也可用。这允许你使用反应模式(调用toObservalble()方法或observe()方法或异步使用(调用queure()方法))。
通过设置feign.hystrix.enabled=false来禁用Feign对Hystrix的支持。
在每个客户端上通过创建返回值为Feign.Builder的注解为@Scope(“prototype”),可以实现禁用Hystrix的支持。
- Feign Hystrix Fallbacks
Hystrix supports the notion of a fallback: a default code path that is executed when they circuit is open or there is an error. To enable fallbacks for a given @FeignClient set the fallback attribute to the class name that implements the fallback.
译:Hystrix支持回退概念:当断路器开启或发生错误时默认代码路径将会被执行。要为给定的@FeignClient启动回退,将fallback属性设置为实现回退的类名。
简单来说,就是在注解@FeignClient的属性fallback设置为实现了回退的类的类名。
下面用实际代码展示上面的实现:
我们这里以工程microservice-consumer-movie-feign为例:
1) 在接口UserFeignClient中添加类HystrixClientFallback(该类实现了UserFeignClient接口,并重写接口中的方法)。该类代码如下:
@FeignClient(name = "microservice-provider-user", fallback = UserFeignClient.HystrixClientFallback.class)
public interface UserFeignClient {
/**
* 这里需要注意的两个地方
* <p>
* 1、在这里不支持GetMapping注解,如果用这个注解,不能启动
* <p>
* 2、@PathVariable需要设置value,如果不设置也不能成功启动
*
* @param id
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/simple/{id}")
public User findById(@PathVariable("id") Long id);
// @Component
static class HystrixClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
System.out.println("----fallback----");
User user = new User();
user.setId(0L);
return user;
}
}
}
2) 根据官网API的说明,我们这里将注解@FeignClient的属性fallback的值设置为实现了回退方法的类HystrixClientFallback。
3) 完成上面步骤之后,我们先后启动eureka-server、microservice-provider-user等服务,然后再启动microservice-consumer-movie-feign服务,发现microservice-consumer-movie-feign启动报错。
Caused by: java.lang.IllegalStateException: No fallback instance of type class com.spring.cloud.feign.UserFeignClient$HystrixClientFallback found for feign client microservice-provider-user
错误提示:feign客户端microservice-provider-user没有fallback实例类型com.spring.cloud.feign.UserFeignClient$HystrixClientFallback被发现。也就是说不能找到这个HystrixClientFallback类。
好,解决这个问题的办法就是我们要在HystrixClientFallback类上添加注解@Component。重启即可正常启动,然后通过浏览器访问http://localhost:8011/movie/1
发现可以正常获得用户信息,也没有进入到HystrixClientFallback类中得分findById方法中,那么现在我们停掉microservice-provider-user服务,然后再重新访问http://localhost:8011/movie/1 发现这次请求进入了HystrixClientFallback类中的findById方法。