SpringCloud(四)服务保护机制Hystrix

背景理论
假设Tomcat最大线程数是10个, 这个客户端发来100个请求, 就会有90个请求被等待. 当这10个请求有谁完成之后, 在去从90个里面取出一个继续处理. 如果请求量巨大, 则会导致部分接口长时间处于等待状态. 如果高并发情况下,甚至导致服务器直接宕机。

为了解决这种高并发情况下,导致服务不可用的情况下,断路器就排上用场了。可以把断路器理解为保险丝,保险丝是怎么工作的,当电流过大时,承受不了,我直接断开,不给你通电了。断路器也是一样的,既然我一次只能处理10个请求,那我就只接受10个,多了我不接,因为就算接了,我也处理不了,搞不好,把自己都给搞废了。

服务雪崩

Tomcat默认情况下, 只有一个线程池去处理客户端发来的所有请求, 线程池里的线程数是有上线的, 这样在高并发的情况下, 如果客户端所有的请求都访问同一个接口, 导致线程池的所有线程都去处理该接口, 但是也会导致其它服务没有线程接受请求, 这就是服务的雪崩效应.

服务降级

在高并发情况下,防止用户一直等待,使用服务降级方式(直接返回一个友好的提示给客户端,调用fallBack方法)
如果调用其他接口超时的时候(默认是1秒时间), 如果一秒没有响应的话, 会直接走降级的方法.

服务熔断(类似保险丝)

熔断机制目的为了保护服务,在高并发的情况下,如果请求达到一定极限(可以自己设置阔值)如果流量超出了设置阈值,直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用

服务隔离

因为默认情况下,只有一个线程池会维护所有的服务接口,如果大量的请求访问同一个接口,达到tomcat 线程池默认极限,可能会导致其他服务无法访问。
解决服务雪崩效应:使用服务隔离机制(线程池方式和信号量),使用线程池方式实現隔离的原理: 相当于每个接口(服务)都有自己独立的线程池,因为每个线程池互不影响,这样的话就可以解决服务雪崩效应。
线程池隔离:
每个服务接口,都有自己独立的线程池,每个线程池互不影响。
信号量隔离:
使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,当请求进来时先判断计数器的数值,若超过设置的最大线程个数则拒绝该请求,若不超过则通行,这时候计数器+1,请求返 回成功后计数器-1。

服务限流

服务限流就是对接口访问进行限制,常用服务限流算法令牌桶、漏桶。计数器也可以进行粗暴限流实现。

SpringCloud(四)服务保护机制Hystrix_第1张图片
屏幕快照 2019-04-22 上午9.42.28.png

hystrix断路器maven依赖

        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        

yml文件配置

###开启Hystrix断路器 
feign:
  hystrix:
    enabled: true
#### hystrix服务超时时间, 默认超时时间是1秒
hystrix:  
 command: 
   default: 
      execution: 
       timeout: 5000
        enabled: true

hystrix服务超时时间这个配置很重要, 如果使用HystrixCommand的接口中访问了其他的Api, 如果不配置, 会直接走服务降级的访问, 因为默认访问超时时间是1秒.

@HystrixCommand注解使用

默认开启服务隔离方式 以线程池方式
默认开启服务降级执行方法(callback)
默认开启服务熔断机制(hystrix.threadpool.default.coreSize(默认为10)

    @HystrixCommand(fallbackMethod = "hystrixFallback")
    @RequestMapping("/hystrixApi")
    public String orderToMemberUserInfoHystrix() {
        System.out.println("orderToMemberUserInfoHystrix:" + "线程池名称:" + Thread.currentThread().getName());
                // 如果这里又调用了其他的服务, 这个调用服务的线程和orderToMemberUserInfoHystrix处理逻辑的线程是同一个线程
        return "hello";
    }

    public String hystrixFallback() {
        return "服务降级,服务器忙,请稍后重试!";
    }

启动类添加@EnableHystrix注解

当访问hystrixApi时, 如果访问量超出Tomcat最大处理量时, 则会走降级hystrixFallback()方法.

再添加一个接口用于测试服务隔离

    @RequestMapping("/segregateApi")
    public String segregateApi() {
        System.out.println("orderInfo:" + "线程池名称:" + Thread.currentThread().getName());
    }

当分别访问segregateApi接口和hystrixApi时, 线程名称是不同的, 所以hystrix默认是做了服务隔离的, 假设segregateApi服务被大量线程访问, 发生服务降级了, hystrixApi是不会受到影响的.

使用类的方法使用断路器

@FeignClient(value = "app-member", fallback = MemberFallback.class)
public interface MemberServiceFeigin  {
    @RequestMapping("/getMember")
    public UserEntity getMember(@RequestParam("name") String name);

    @RequestMapping("/getUserInfo")
    public ResponseBase getUserInfo();
}

@FeignClient是使用feign调用服务的注解, value = "app-member"是需要调用的服务的名称, fallback = MemberFallback.classfallback是发生错误时的回调
实现MemberFallback

@Component
public class MemberFallback implements MemberServiceFeigin {

@Override
    public UserEntity getMember(String name) {
        // TODO Auto-generated method stub
        return null;
    }
@Override
    public ResponseBase getUserInfo() {

        return setResultError("服务器忙,请稍后重试!");
    }

}

当调用发生失败时, 会进入对应的fallback处理方法. 而且这种方式实现服务降级, 自动开启线程隔离. 其线程与服务调用放的线程是独立分开的.

你可能感兴趣的:(SpringCloud(四)服务保护机制Hystrix)