SpringCloud全家桶(三):搞定 Hystrix

Hystrix 是springcloud生态的断路器(隔离、限流、降级),主要是用来预防服务雪崩现象,剔除掉分布式系统中某些挂掉或请求过慢的服务节点。Hystrix 是一个帮助解决分布式系统中超时处理和容错的类库, 拥有保护系统的能力。

Hystrix的设计原则,

  • 防止任何单个依赖项耗尽所有容器(如Tomcat)用户线程
  • 甩掉包袱,快速失败而不是排队
  • 在任何可行的地方提供回退,以保护用户不受失败的影响。
  • 使用隔离技术(如隔离板、泳道和断路器模式)来限制任何一个依赖项的影响
  • 通过近实时的度量、监视和警报来优化发现时间。
  • 通过配置的低延迟传播来优化恢复时间。
  • 支持对Hystrix的大多数方面的动态属性更改,允许使用低延迟反馈循环进行实时操作修改。
  • 避免在整个依赖客户端执行中出现故障,而不仅仅是在网络流量中。

一、Hystrix 的隔离策略(隔离、限流、降级)

微服务使用Hystrix熔断器实现了服务的自动降级,让微服务具备自我保护的能力,提升了系统的稳定性,也较好的解决雪崩效应。Hystrix断路器有两种隔离策略:信号量隔离(默认)和线程池隔离

1、信号量模式

信号量模式,从始至终都只有请求线程自身,是同步调用模式,不支持超时调用,不支持直接熔断,由于没有线程的切换,开销非常小。

信号量隔离,常用于获取共享资源的场景中,比如计算机连接了两个打印机,那么初始的信号量就是2,被某个进程或线程获取后减1,信号量为0后,一般情况下,需要获取的线程或进程进入资源等待状态。Hystrix的处理有些不同,其不等待,直接返回失败。

2、线程池模式

线程池模式,可以支持异步调用,支持超时调用,支持直接熔断,存在线程切换,开销大

线程池隔离,采用的就是jdk的线程池,其默认选用不使用阻塞队列的线程池,例如线程池大小为10,如果某时刻10个线程均被使用,那么新的请求将不会进入等待队列,而是直接返回失败,起到限流的作用。

3、断路器机制

断路器机制,当断路器处于打开状态时,直接返回失败或进入降级流程。断路器打开和关闭的触发流程为,

  • 当总的请求数达到阈值或总的请求失败百分比达到了阈值时,将断路器的状态由关闭设置为打开。
  • 当断路器打开时,所有的请求均被短路,在经过指定休眠时间窗口后,让下一个请求通过(断路器被认为是半开状态)。如果请求失败,断路器进入打开状态,并进入新的休眠窗口;否则进入关闭状态。

二、Hystrix 的整体处理流程

流程如上图所示,Hystrix 框架通过命令模式来实现方法粒度上的服务保障。

  • HystrixCommand 类,提供同步的execute和异步的queue方法。
  • HystrixObservableCommand 类提供立即执行observe和延迟执行toObservable的回调方法。
  • 此外,实际项目中通常不会使用Hystrix集成的本地缓存。

三、 Hystrix 如何解决服务间的依赖调用隔离

微服务分布式架构下,众多的服务节点,没有断路器的保护,挂掉或者响应慢的节点有引发服务雪崩的风险,我们来看下 Hystrix 是如何解决服务间的依赖调用的。

  • Hystrix 使用命令模式 HystrixCommand 包装依赖调用逻辑,每个命令在单独线程中/信号授权下执行。
  • 可配置依赖调用超时时间,超时时间一般设为比99.5%平均时间略高即可。当调用超时时,直接返回或执行fallback逻辑
  • 为每个依赖提供一个小的线程池(或信号),如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间
  • 依赖调用结果分:成功,失败(抛出异常),超时,拒绝,短路。 请求失败(异常,拒绝,超时,短路)时执行 fallback(降级)逻辑。
  • 提供熔断器组件,可以自动运行或手动调用,停止当前依赖一段时间(10秒),熔断器默认错误率阈值为50%,超过将自动运行。
  • 提供近实时依赖的统计和监控。

四、Hystrix 的使用示例

1、在springcloud中的使用

Hystrix 在springcloud中的使用,我们主要关注两个注解 @EnableCircuitBreaker 和 @HystrixCommand

  • @EnableCircuitBreaker,加在程序的启动类上,表明开启Hystrix断路器。
  • @HystrixCommand,加在具体的方法上,实现断路器功能,可以加 fallbackMethod 等参数。

a、启动类上开启Hystrix断路器

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker // 开启 Hystrix 断路器
public class RibbonConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

b、方法上加@HystrixCommand注解,实现断路器功能

@Service
public class ConsumerService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "helloFallback") 
    public String helloService() {
        return restTemplate.getForEntity("http://service-1/sayHi", String.class).getBody();
    }

    public String helloFallback(){
        return "exception....";
    }
}

2、Hystrix 命令设计模式

此方式较繁琐,不常用,建议直接在springcloud模式下使用,只需两个注解。

Hystrix使用了命令设计模式,只需要编写命令,继承HystrixCommand类,如下,

public class CommandHelloWorld extends HystrixCommand<String> {
 
    private final String name;
 
    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("HelloWorld"));
        this.name = name;
    }
 
    @Override
    protected String run() throws Exception { // 完成业务逻辑
        return "Hello " + name + "!";
    }
 
    @Override
    protected String getFallback() { // run方法抛出异常的时候返回备用结果
        return "Hello Failure " + name + "!";
    }
 
}

测试,

@Test
public void test() {
    assertEquals("Hello World!", new CommandHelloWorld("World").execute());
    assertEquals("Hello Format!", new CommandHelloWorld("Format").execute());
}

五、hystrix-dashboard 监控

Hystrix Dashboard 提供了对于微服务调用状态的监控信息,需要结合spring-boot-actuator模块一起使用。Hystrix Dashboard 主要用来实时监控Hystrix的各项指标信息。通过Hystrix Dashboard反馈的实时信息,可以帮助我们快速发现系统中存在的问题。

1、引入依赖

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

2、启动类开启 @EnableHystrixDashboard 注解

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardApplication {
  public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
  }
}

3、访问监控页面

启动后,访问 http://localhost:port/hystrix.stream

发布了131 篇原创文章 · 获赞 127 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/shipfei_csdn/article/details/103989545