雪崩效应:也叫作级联故障,下游服务故障,拖跨上游服务,沿着服务调用链路逐级向上传播,造成上游服务大规模故障。
容错: 在分布式系统中,某些服务出现问题时,不会影响、拖垮其它服务(上游服务),其它服务依然可用、可对外提供服务。
提高系统容错的常见方法
超时机制
设置超时时间,如果在指定时间内未完成自动释放占用的资源。
限流
限制请求数量,当大量请求涌入时使部分请求快速失败,防止大量请求涌入冲垮服务。
可以设置不同层面的限流
- nginx
- 网关:常见限流框架比如guava
- 服务消费者:限制的是对提供者发起的调用请求
可用性指的是服务能完成请求的处理,快速失败也是一种处理方式,此时也认为服务是可用的。
服务降级
服务调用请求快速失败之后,执行预案(回退方法)代替服务调用。
断路器
监控服务调用的失败率,失败率达到阈值时断路器打开、熔断链路,防止下游服务的故障影响到上游服务,后续的服务调用请求直接快速失败。
断路器打开5min后,会开启5min的窗口期,窗口期内断路器半开、放行部分服务调用请求,以检测下游服务是否已修复,如果已修复则关路器关闭、链路恢复;如果未修复则打开断路器,等下一个窗口期再进行检测,循环往复,直到链路恢复。5min是默认值,数值可调。
常常多种方式搭配使用。
hystrix简介
hystrix是一个容错框架,提供了服务限流、服务降级、断路器、服务监控等功能。
hystrix将对不同的调用请求隔离开,某个调用请求失败时也不会影响到其它的调用请求。
hystrix的隔离策略有2种
- THREAD:线程池,默认的隔离策略。将每个服务调用请求都包装为一个线程,放到线程池中。线程池中的服务调用请求都是正在执行的,线程池满了就放到队列中排队等待,如果队列也满了就让后续的服务调用请求直接快速失败。
- SEMAPHORE:信号量,信号量即可同时执行的调用请求个数,默认值10。发起一个调用请求时,将信号量-1;完成一个调用请求时将信号量+1;信号量为0时使后续的调用请求直接快速失败。
信号量适用于高并发的调用,因为高并发时线程池中线程数极多,资源开销大。信号量一般只用于非网络调用。
hystrix的2种使用方式
feign集成了hystrix,可以使用feign内置的hystrix,也可以直接使用hystrix。
使用feign自带的hystrix
在消费者中搭配feign使用,只能对服务调用进行容错保护。
1、yml
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){
}
}
4、yml
使用feign内置的hystrix时不能在yml配置hystrix的相关参数,直接使用hystrix则可以
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD #指定隔离策略,默认线程池
thread:
timeoutInMilliseconds: 4000 #指定方法执行的超时时间,默认1000,ms,指定时间内未完成就认为失败,执行回退方法
#semaphore:
#maxConcurrentRequests: 100 #如果使用信号量,可以指定信号数