服务雪崩:
多个微服务之间调用的时候,架设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用相应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统奔溃,即所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
Hystrix是一个用于处理风不是系统的延迟容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(Fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就能保证服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
服务熔断(是在服务提供者端实现,也就是服务端)
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者相应时间太长时,会进行服务的降级,进而熔断该阶段微服务的调用,快速返回“错误“的相应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。熔断机制的注解是@HystrixCommand。
熔断是某个服务故障或者异常引起。类似显示中的保险丝,当某个异常条件被处罚,直接熔断掉整个服务,而不是一直等到次服务超时。
简单使用:(下面这种方式没有将异常处理方法与业务逻辑分离,如果有N多个方法,那么需要些N多个对应的fallbackMethod的方法回调,耦合度高,而且方法膨胀)
1、创建带熔断功能服务提供者的工程,可以参考不带熔断的工程,在pom文件中加入Hystrix的依赖,其他的依赖于不带熔断的工程相同
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2、修改配置文件,使该服务注册到Eureka中心显示自己的名字
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: microservicecloud-dept-hystrix8001
prefer-ip-address: true
3、在controller层添加熔断注解,并编写相应的方法,注意:调用熔断方法的返回值与调用方法的返回值需要类型一致
@RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET)
//一旦调用失败抛出异常信息之后,会自动调用@HystrixCommand标注的fallbackMethod中定义的方法
@HystrixCommand(fallbackMethod = "processHystrix_get")
public Dept get(@PathVariable("id") Long id) {
Dept dept = deptService.getById(id);
if(dept == null) {
throw new RuntimeException("该ID:"+id+"没有对应的信息!");
}
return dept;
}
public Dept processHystrix_get(@PathVariable("id") Long id) {
Dept dept = new Dept(id,"no_dpart","no_data_in_database");
return dept;
}
4、在主启动类上添加相应的注解,表示启用相关功能
@SpringBootApplication
@EnableEurekaClient
//做服务发现用的
@EnableDiscoveryClient
@EnableCircuitBreaker//也可用@EnableHystrix代替,@EnableHystrix包含@EnableCircuitBreaker
public class DeptProviderHystrix8001_app {
public static void main(String args[]) {
SpringApplication.run(DeptProviderHystrix8001_app.class, args);
}
}
服务降级(是在消费者端完成的,也就是客户端,与服务端没有关系)
整体资源快不够了,将某些服务先关掉,待资源恢复之后,再开启。那么在服务关闭后,客户端访问服务,需要给客户端返回友好的响应。
所谓降级,一般是从整体负荷考虑,就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的Fallback回调,返回一个缺省值。这样做,虽然服务水平下降,但是仍然可用,比直接挂掉要好。
简单使用:
1、修改api工程,根据已有DeptClientService接口新建一个实现FallbackFactory接口的类DeptClientServiceFallbackFactory
//该FallbackFactory实现类是为了处理接口DeptClientService中所有方法出现异常时的回调方法
//这种就无需再服务提供者的业务逻辑中添加相应的回调方法。@Component必须添加
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {
@Override
public DeptClientService create(Throwable cause) {
// TODO Auto-generated method stub
return new DeptClientService() {
@Override
public boolean add(Dept dept) {
// TODO Auto-generated method stub
return false;
}
@Override
public Dept get(Long id) {
// TODO Auto-generated method stub
Dept dept = new Dept(id,"no_dpart","no_data_in_database");
return dept;
}
@Override
public List<Dept> list() {
// TODO Auto-generated method stub
return null;
}
};
}
}
2、在相应的接口中对@FeignClient注解添加fallbackFactory的设置
//通过@FeignClient标注该接口是一个Feign调用的接口,指定微服务名来绑定与哪个服务提供者交互
//通过fallbackFactory指定对接口中的方法需要做降级处理
@FeignClient(name = "microservicecloud-dept",fallbackFactory = DeptClientServiceFallbackFactory.class)
public interface DeptClientService {
//映射请求与服务提供者中的controller映射请求相同,实际上消费者客户端通过该接口方法时,实际上是
//调用了microservicecloud-dept微服务中请求为/dept/add的controller中的对应方法
@RequestMapping(value="/dept/add",method = RequestMethod.POST)
public boolean add(Dept dept);
@RequestMapping(value = "/dept/get/{id}",method = RequestMethod.GET)
public Dept get(@PathVariable("id") Long id);
@RequestMapping(value = "/dept/list",method = RequestMethod.GET)
public List<Dept> list();
}
服务监控HystrixDashboard
除了隔离依赖服务的调用外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求,多少成功,多少失败等。
简单使用:
1、创建Hystrix-Dashboard的工程,在pom文件中添加Hystrix的相关依赖
<!-- hystrix和hystrixDashbord -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
2、配置文件中只需要配置端口号即可
server:
port: 9001
3、修改主启动类
@SpringBootApplication
@EnableHystrixDashboard
public class DeptConsumerHystrixDashbord_app {
public static void main(String[] args) {
SpringApplication.run(DeptConsumerHystrixDashbord_app.class, args);
}
}
4、在服务提供者的pom中添加监控依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
5、访问
可以对具体的微服务进行监测
实心圆:共有两种含义,通过颜色变化代表了实例的健康程度,健康程度绿色、黄色、橙色、红色依次递减。同时实心圆的大小也会根据实例请求流量发生变化,流量越大实心圆就越大,所以通过实心圆展示,就可以在大量的实例中快速发现故障实例和高压实例