目录
相关概念
容错
在分布式系统中,某个版块可能会出现问题,比如连接超时、发生异常,需要用一些方式提升系统容错,在一些板块出问题时,系统也能正常运行、依然可用,不会被某个板块的问题拖垮。
Hystrix是一个容错框架,提供了服务限流、服务降级、熔断、监控、cache等功能,可以有效阻止服务调用故障造成的级联故障。
服务限流
当消费者对某提供者的调用请求个数较多时,消费者可以限制自身对提供者发起的请求个数,请求个数超过指定值时,使请求快速失败。服务限流将正常请求、快速失败的请求隔离开来,也叫作隔离策略。
Hystrix的限流方式有2种:线程池、信号量。
1、THREAD 线程池,默认的隔离策略
将每个服务调用请求都包装为一个线程,放到服务调用的线程池中。线程池中的服务调用请求都是正在执行的,线程池满了就放到队列中排队等待,队列满了就让后续的服务调用请求快速失败。
2、SEMAPHORE 信号量
信号量即可同时执行的服务调用请求个数,默认值10。进行一次服务调用,将信号量-1;完成一个调用请求将信号量+1;信号量为0时使后续服务调用请求快速失败。
信号量适用于高并发的服务调用,因为高并发时线程池中线程数极多,资源开销大。信号量一般只用于非网络调用。
断路器
消费者监控服务调用请求的失败率,失败率达到阈值时打开断路器,熔断链路,切断下游服务,防止下游服务的故障影响到上游服务,后续的服务调用请求快速失败。
断路器打开后自动开启5min的窗口期(数值可调),窗口期内的服务调用请求都快速失败,5min后断路器半开,放行部分服务调用请求,如果这些服务调用请求都成功了,说明问题已修复,关闭断路器,链路恢复通行,即链路的自我修复。
服务降级
服务调用请求(快速)失败之后,会执行预案(回退方法)代替服务调用。
hystrix用于限制服务调用,自然是在服务消费者中使用的。
feign集成了hystrix,可以直接使用hystrix,也可以使用feign自带的hystrix。
使用Feign自带的Hystrix
这种方式需要和feign搭配使用
1、在application.yml中启用feign自带的hystrix
feign:
hystrix:
enabled: true
2、在feign包下编写服务调用的回退类
@Component //放到spring容器中
public class OrderServiceFeignFallback implements OrderServiceFeign { //实现feign接口
//实现的方法就是接口中对应方法的回退方法
@Override
public List<Order> findOrdersByUserId(Integer userId) {
}
}
3、在feign接口中指定回退类
@FeignClient(name = "order-service", fallback = OrderServiceFeignFallback.class) //指定回退类
public interface OrderServiceFeign {
@GetMapping("/api/v1/order/list/{user_id}")
List<Order> findOrdersByUserId(@PathVariable("user_id") Integer userId);
}
直接使用Hystrix
1、创建时勾选Spring Cloud Circuit Breaker -> Hystrix [Maintenance],或者手动添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、引导类上加 @EnableCircuitBreaker或@EnableHystrix
3、指定回退方法
@Service
public class UserService {
@Autowired
private OrderServiceFeign orderServiceFeign; //注入要使用的Feign接口
@HystrixCommand(fallbackMethod = "findOrdersByIdFallback") //指定回退方法
public List<Order> findOrdersById(Integer userId){
return orderServiceFeign.findOrdersByUserId(userId);
}
// 回退方法。参数表、返回值类型要与原方法相同
public List<Order> findOrdersByIdFallback(Integer userId){
}
}
2种方式的对比
- 第一种要和feign搭配使用,第二种无此要求
- 第一种只作用于服务调用,第二种可以作用于所有方法,不局限于消费者、服务调用,可以给所有方法指定回退方法、添加容错保护
- 第一种更加方便、好维护
- 第二种可以在application.yml中配置hystrix相关参数,第一种则不能
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD #指定隔离策略,默认线程池
thread:
timeoutInMilliseconds: 4000 #指定方法执行的超时时间,默认1000,ms,指定时间内未完成就认为失败,执行回退方法
#semaphore:
#maxConcurrentRequests: 100 #如果使用信号量,可以指定信号数
Hystrix 的监控仪表盘(了解)
实际开发中用得不多,了解即可
actuator 监控服务调用
1、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、application.yml
management:
endpoints:
web:
exposure:
include: "*" #监控服务调用的所有数据,默认只监控部分数据
3、访问 127.0.0.1:8781/actuator/hystrix.stream ,ip、port换为消费者的
刷新服务调用,已经监控到数据
dashboard 仪表盘
上面密密麻麻的数据不直观,hystrix提供了仪表盘来直观展示监控到的数据。仪表盘可以在消费者中配置,也可以单独写一个子模块作为仪表盘
1、创建时勾选Spring Cloud Circuit Breaker -> Hystrix DasdBoard [Maintenance],或者手动添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
如果单独用一个服务来作为仪表盘,只加这个依赖即可,这个依赖中已经包含了spring-boot-start-web
2、引导类上加 @EnableHystrixDashboard
3、springboot web项目默认使用8080端口,如果单独使用一个服务作为仪表盘,看是否需要修改端口
4、访问 127.0.0.1:8080/hystrix , ip、port换为仪表盘所在模块的
输入要监控的 actuator 的地址,仪表盘启动时会在console打印可监控的actuator地址