Hystrix简介
在分布式环境中,许多服务依赖项中的一些必然会失败。
比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。
Hystrix是一个库,提供了熔断、隔离、Fallback、cache、监控等功能,
能够在一个、或多个依赖同时出现问题时保证系统依然可用
通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、
停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。
Hystrix被设计的目标?
1.对通过第三方客户端库访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。
2.在复杂的分布式系统中阻止级联故障。
3.快速失败,快速恢复。
4.回退,尽可能优雅地降级。
5.启用近实时监控、警报和操作控制。
Hystrix解决了什么问题?
复杂分布式体系结构中的应用程序有许多依赖项,每个依赖项在某些时候都不可避免地会失败。
如果主机应用程序没有与这些外部故障隔离,那么它有可能被他们拖垮。
Hystrix设计原则是什么?
1.防止任何单个依赖项耗尽所有容器(如Tomcat)用户线程。
2.甩掉包袱,快速失败而不是排队。
3.在任何可行的地方提供回退,以保护用户不受失败的影响。
4.使用隔离技术(如隔离板、泳道和断路器模式)来限制任何一个依赖项的影响。
5.通过近实时的度量、监视和警报来优化发现时间。
6.通过配置的低延迟传播来优化恢复时间。
7.支持对Hystrix的大多数方面的动态属性更改,允许使用低延迟反馈循环进行实时操作修改。
8.避免在整个依赖客户端执行中出现故障,而不仅仅是在网络流量中。
Hystrix基本使用
pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
启动类添加注解
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
@EnableCircuitBreaker //启用熔断
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
application.yml(同Feign)
server:
port: 9095
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://root:123456@localhost:10000/eureka/
logging:
level:
com.springcloud.hystrix.feignclient.IFeignClient: DEBUG
@HystrixCommand注解指定超时方法
@RestController
public class FeignController {
@Autowired
private IFeignClient feignClient;
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id){
return feignClient.getUser(id);
}
//指定超时访问的方法
@HystrixCommand(fallbackMethod = "defaultStores")
@GetMapping("/getuserpojo")
public User getUserPojo(User user){
return feignClient.getUserPojo(user);
}
//超时将访问此方法
public User defaultStores(User user) {
User us1 = new User();
us1.setId(-100l);
us1.setAddress("请求超时");
us1.setUsername("请求超时");
return us1;
}
}
Feign使用Hystrix
application.yml
server:
port: 9095
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://root:123456@localhost:10000/eureka/
feign:
hystrix:
enabled: true #开启hystrix
#设置超时时间(单位:毫秒。默认为1秒)
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
logging:
level:
com.springcloud.hystrix.feignclient.IFeignClient: DEBUG #给指定的FeignClient设置日志输出级别,只有debug才会打印日志
FeignClient接口
//加上fallback参数,指定请求失败访问的类,也就是该接口的实现类
@FeignClient(name = "provider", configuration = FeignConfig.class, fallback = FeignClientService.class)
public interface IFeignClient {
@RequestLine("GET /user/{id}") //组合注解,第一个是请求方式,第二个是参数,用空格分割
User getUser(@Param("id") Long id);//此处@PathVariable注解需要改成@Param注解,否则报错
@RequestLine("POST /getuserpojo")
User getUserPojo( User user);
}
请求失败访问的类
//该类实现了FeignClient接口,实现的方法为访问失败后执行的方法
@Component
public class FeignClientService implements IFeignClient {
@Override
public User getUser(Long id) {
User user = new User();
user.setId(-100l);
user.setUsername("超时请求");
return user;
}
@Override
public User getUserPojo(User user) {
User user2 = new User();
user2.setId(-101l);
user2.setUsername("超时请求");
return user2;
}
}
controller
//此处就不需要@HystrixCommand注解了
@RestController
public class FeignController {
@Autowired
private IFeignClient feignClient;
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id){
return feignClient.getUser(id);
}
@GetMapping("/getuserpojo")
public User getUserPojo(User user){
return feignClient.getUserPojo(user);
}
}
使用FallbackFactory
FeignClient接口
//fallbackFactory参数指向实现类
@FeignClient(name = "provider", configuration = FeignConfig.class,fallbackFactory = FeignClientFallBackFactory.class)
public interface IFeignClient {
@RequestLine("GET /user/{id}") //组合注解,第一个是请求方式,第二个是参数,用空格分割
User getUser(@Param("id") Long id);//此处@PathVariable注解需要改成@Param注解,否则报错
@RequestLine("POST /getuserpojo")
User getUserPojo( User user);
}
fallbackFactory实现类
//这里要实现FallbackFactory,泛型定义为FeignClient接口
public class FeignClientFallBackFactory implements FallbackFactory<IFeignClient> {
//这里返回该接口类,并重写了方法作为失败后的处理方法
@Override
public IFeignClient create(Throwable throwable) {
return new IFeignClient() {
@Override
public User getUser(Long id) {
User user2 = new User();
user2.setId(-100l);
user2.setUsername("超时请求1");
return user2;
}
@Override
public User getUserPojo(User user) {
User user2 = new User();
user2.setId(-101l);
user2.setUsername("超时请求2");
return user2;
}
};
}
}
Hystrix监控
pom依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
application.yml
server:
port: 9096
spring:
application:
name: feign
eureka:
client:
service-url:
defaultZone: http://root:123456@localhost:10000/eureka/
#这个如果不加,访问不到监控页面
management:
endpoints:
web:
exposure:
include: "*"
feign:
hystrix:
enabled: true #开启hystrix
#设置超时时间(单位:毫秒。默认为1秒)
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
logging:
level:
com.springcloud.hystrix.feignclient.IFeignClient: DEBUG #给指定的FeignClient设置日志输出级别,只有debug才会打印日志
启动类添加注解
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
@EnableCircuitBreaker //启用熔断
@EnableHystrixDashboard //启用监控
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
启动测试
访问:http://127.0.0.1:9096/hystrix
流监控:http://127.0.0.1:9096/actuator/hystrix.stream
将流监控网址填写到监控主页即可
注意:需要监控的服务添加actuator监控依赖支持
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>