SpringCloud:Hystrix(服务熔断、服务降级)

1、分布式系统面临的问题

(1)服务雪崩

  多个微服务之间调用的时候,假设微服务A调用微服务B和C,微服务B和C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,引起所谓的“雪崩效应”。

  对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

(2)解决方案

  • 熔断模式

  这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。

  • 隔离模式

  这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火烧光了,不会影响到其他的小岛。例如:可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。这种模式使用场景非常多,例如将一个服务拆开,对于重要的服务使用单独服务器来部署,再或者公司最近推广的多中心。

  • 限流模式

  上述的熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式。限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。

 

2、服务熔断

(1)概念

  当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回"错误"的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败就会启动熔断机制。

(2)实现

  • 模仿8001端口新建Hystrix模块(服务的提供者)

添加依赖:

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-hystrix</artifactId>
   </dependency>

配置文件中修改服务的名称:

  instance:
    instance-id: my8001-hystrix
    prefer-ip-address: true

定义Controller:

  一旦调用GET方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。但是,此种方式会存在一个问题就是每一个方法都需要一个处理

@RestController
public class DeptController {
    @Autowired
    private DeptService service = null;

    @RequestMapping(value="/dept/get/{id}",method= RequestMethod.GET)
    @HystrixCommand(fallbackMethod = "processHystrix_Get")
    public Dept get(@PathVariable("id") Long id)
    {
        Dept dept =  this.service.get(id);
        if(null == dept)
        {
            throw new RuntimeException("该ID:"+id+"没有没有对应的信息");
        }
        return dept;
    }

    public Dept processHystrix_Get(@PathVariable("id") Long id)
    {
        return new Dept().setDeptno(id)
                .setDname("该ID:"+id+"没有没有对应的信息,null--@HystrixCommand")
                .setDb_source("no this database in MySQL");
    }

}

在启动类中添加对hystrixR熔断机制的支持

@EnableCircuitBreaker
  • 测试

SpringCloud:Hystrix(服务熔断、服务降级)

 SpringCloud:Hystrix(服务熔断、服务降级)

 

3、服务降级

(1)概念

整体资源不足,将某些服务先关掉,待渡过难关,再重新开启,服务降级是在客户端完成的。

(2)实现

  • API模块(公共模块)

  新建一个实现了FallbackFactory接口的类DeptClientServiceFallbackFactory,该接口是专门处理异常的,与上面的服务熔断处理异常的方式相比,此种方式实现了逻辑与异常处理业务的分离

@Component
public class DeptClientServiceFallbackFactory implements
        FallbackFactory<DeptClientService> {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public Dept get(long id) {
                return new Dept().setDeptno(id)
                        .setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
                        .setDb_source("no this database in MySQL");
            }

            @Override
            public List<Dept> list() {
                return null;
            }

            @Override
            public boolean add(Dept dept) {
                return false;
            }
        };
    }
}

在API模块中的业务接口的注解中添加属性:

@FeignClient(value = "PROVIDER",fallbackFactory=DeptClientServiceFallbackFactory.class)
public interface DeptClientService {
    @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();

    @RequestMapping(value = "/dept/add",method = RequestMethod.POST)
    public boolean add(Dept dept);
}
  • Feign模块(消费者模块)
feign: 
  hystrix: 
    enabled: true

(3)测试

SpringCloud:Hystrix(服务熔断、服务降级)

 

 

 在只启动一个服务的提供者(8001)的情况下,能够正常访问,当讲该服务关闭的时候能够给出提示信息。也就是说在服务端不可用的时候客户端能够得到提示,而不是挂起。

 

 

 

上一篇:Feign拦截器熔断机制踩坑?


下一篇:hystrix