目录
1、什么是服务雪崩?
在分布式的链路中,只要有一个服务宕机,那么就可能导致一整个业务线都瘫痪。
服务雪崩的本质:线程没有及时回收。
不管是调用成功还是失败,只要线程可以及时回收,就可以解决服务雪崩
2、Spring Cloud Hystrix 简介
熔断器,也叫断路器!(正常情况下 断路器是关的 只有出了问题才打开)用来保护微服务不 雪崩的方法。思想和我们上面画的拦截器一样。 Hystrix 是 Netflix 公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现 联动故障。Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从 而提高了整个分布式系统的弹性。微博 弹性云扩容 Docker K8s;
3、代码实现
我们这里创建两个服务,一个customer-service(客户)服务,一个rent-car-service(租车)服务。我们使用customer-service远程调用rent-car-service;如果rent-car-service服务宕机或者关闭,customer-service就会调用超时,如果我们加上hystrix来使用熔断功能,rent-car-service服务宕机时,会使用备选方案。
3.1、创建rent-car-service服务
1、导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、启动类上添加@EnableEurekaClient注解
3、编写配置文件
server:
port: 8080
spring:
application:
name: rent-car-service #服务名称
eureka:
client:
service-url:
defaultZone: http://ip:8761/eureka #服务注册
instance:
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
4、编写接口
@RestController
public class RentCarController {
@GetMapping("/rent")
public String rent(){
return "租车成功";
}
}
3.2、创建customer-service服务
1、导入依赖
依赖比rent-car-service服务多openfeign和hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--服务熔断-->
<dependency> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、启动类上添加@EnableEurekaClient 注解和@EnableFeignClients注解
3、配置文件相对于rent-car-service服务只需要修改端口号和服务名称
4、编写feign远程调用接口
@FeignClient(value = "rent-car-service")
public interface CustomerRentFeign {
@GetMapping("/rent")
public String rent();
}
5、编写接口发起远程调用
@RestController
public class CustomerController {
@Resource
private CustomerRentFeign customerRentFeign;
@GetMapping("/customerRent")
public String CustomerRent(){
System.out.println("客户来租车了");
//RPC 远程调用
String rent = customerRentFeign.rent();
System.out.println(rent);
return rent;
}
}
3.3、测试feign远程调用
查看erueka注册中心
调用customer-service服务 的customerRent接口:
关闭rent-car-service服务再次调用
3.4、为customer-service服务开启熔断功能
1、修改配置文件
feign:
hystrix:
enabled: true #开启hystrix 默认为false
2、修改CustomerRentFeign接口
3、为发起远程调用的接口CustomerRentFeign创建实现类
@Component
public class CustomerRentFeignHystrix implements CustomerRentFeign {
@Override
public String rent() {
return "我是备胎,租车失败";
}
}
4、此时关闭rent-car-service服务,再次使用customer-service服务远程调用
4、熔断原理
在A服务调用B服务之前有个断路器,默认情况下断路器是关闭的,A服务正常调用B服务;如果B服务出现问题,断路器会打开,就不调用B服务了,A服务直接调用断路器的备选方案。并不是一次访问B服务失败,就打开熔断器;而是在一段时间内多次访问都失败,才会认为B服务是坏的,才会打开熔断器;
断路器的状态说明以及状态转变:
关:服务正常调用 A--->B
开:在一段时间内,调用失败次数达到阀值(5s 内失败 3 次)(5s 失败 30 次的)则断路器