使用SpringCloud实现Java分布式开发【part-3】:Hystrix熔断器的介绍和使用步骤、服务降级和服务熔断及超时时长的配置

SpringCloud简介

Spring Cloud是Spring旗下的项目之一
Spring Cloud并不是一个组件 而是许多组件的集合
其将当下非常流行的一些技术整合到了一起 实现了多个分布式开发中的重要功能
协调了分布式环境中各个系统 并且为各类服务提供模板性的配置

其主要涉及的组件包括:

  • Eureka:注册中心
  • Zuul或Spring Cloud Gateway:服务网关
  • Ribbon:负载均衡
  • Feign:服务调用
  • Hystrix或Resilience4j:熔断器

【在本篇中 将介绍Hystrix熔断器】

Hystrix熔断器

Hystrix熔断器在微服务系统中是一款提供保护机制的组件
是开源的一个延迟和容错库 用于隔离访问远程服务和第三方库 以防止出现级联失败

说到这里 就不得不提雪崩问题

雪崩问题

在微服务中 服务间的调用关系错综复杂 一个请求可能需要调用多个微服务接口才能实现 这会形成非常复杂的调用链路
如下图:一次业务请求 需要调用A、P、H、I四个服务 而这四个服务又可能调用其它服务
在这里插入图片描述
那么问题来了
若此时 某个服务出现了异常
如下图:微服务I 发生异常 请求阻塞了 那么用户请求就不会得到响应 则tomcat的这个线程不会释放
在这里插入图片描述
于是 越来越多的用户请求到来 越来越多的线程会被阻塞:
在这里插入图片描述
服务器支持的线程和并发数有限 若请求一直阻塞 则会导致服务器资源耗尽 从而导致所有其它服务都不可用 形成 【雪崩效应】

此时 就需要用到Hystrix熔断器了

Hystrix解决雪崩问题的手段主要是服务降级 其包括:

  • 线程隔离
  • 服务熔断

一、线程隔离

Hystrix为每个依赖服务调用分配一个小的线程池 用户请求不直接访问服务 而是使用线程池中空闲的线程来访问服务
若线程池已满调用将被立即拒绝 默认不采用排队 加速失败判定时间

当判断到服务不可用(无论什么原因导致的) 即可告诉该线程该服务不可用 不再无限等待了 以提早返回结果
在这里插入图片描述

二、服务降级

服务降级:优先保证核心服务 而 非核心服务不可用或弱可用

用户的请求故障时不会被阻塞 更不会无休止的等待或者看到系统崩溃
至少可以看到一个执行结果(例如 返回友好的提示信息)

服务降级虽然会导致请求失败 但是不会导致阻塞 且最多会影响这个依赖服务对应的线程池中的资源 对其它服务没有影响

三、使用步骤

1、服务降级

①、添加依赖:

消费端添加Hystrix的依赖:

<!-- Hystrix熔断器 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netfilx-hystrix</artifactId>
</dependency>
<!-- hystrix-javanica是一个Hystrix contrib库
是Hystrix的子项目 用于简化Hystrix的使用 提供@HystrixCommand注解 -->
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>RELEASE</version>
</dependency>
②、添加注解

在启动类上添加@EnableCircuitBreaker注解以开启Hystrix的熔断功能:

@SpringBootApplication
//  开启Eureka客户端的发现功能
@EnableDiscoveryClient
//  开启Hystrix的熔断功能
@EnableCircuitBreaker
public class ConsumerApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ConsumerApplication.class,args);;
    }

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

@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker这三个注解可以以一个注解来代替:@SpringCloudApplication

@SpringCloudApplication
public class ConsumerApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ConsumerApplication.class,args);;
    }

    // 注册RestTemplate
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate()
    {
    
    
        return new RestTemplate();
    }
}
③、编写降级逻辑

在要设置降级逻辑的接口方法上添加@HystrixCommand注解:
fallbackMethod属性用于指定失败结果 填写的是方法名

@GetMapping("/{id}")
// @HystrixCommand注解用于编写Hystrix的降级逻辑
// fallbackMethod属性用于指定失败结果 填写的是方法名
@HystrixCommand(fallbackMethod = "queryByIdFallback")
public String queryById(@PathVariable Long id)
{
    
    
    // Ribbon负载均衡
    String url="http://user-service/user/"+id;

    return restTemplate.getForObject(url,String.class);
}

然后再在同个类下编写一个名称对应的降级方法
需要注意的是 返回的是字符串类型
且设置了Hystrix降级逻辑的方法的返回值必须与该方法的返回值一致 都需为String字符串 参数也可一致

// 降级失败方法 返回字符串类型
// 设置了Hystrix降级逻辑的方法的返回值必须与该方法的返回值一致 都需为String字符串
// 参数也可一致
public String queryByIdFallback(Long id)
{
    
    
    System.out.println("查询用户信息失败,编号为:"+id);
    return "网络拥挤,访问失败。";
}
④、测试:

在这里插入图片描述
在这里插入图片描述

还可以对一整个类里的所有方法编写降级方法:

避免了单个编写的麻烦

在该类上添加@DefaultProperties注解 defaultFallback属性用于指定方法名

// 全类的降级方法
@DefaultProperties(defaultFallback = "defaultFallback")

然后 在该类中的要使用Hystrix熔断的方法上添加@HystrixCommand注解
虽然是对所有方法熔断 但还是要添加该注解的 唯一区别就是注解里不再指定方法了

@GetMapping("/{id}")
// 虽然是全类的降级方法 但该注解还是要加的
@HystrixCommand
public String queryById(@PathVariable Long id)
{
    
    
    // Ribbon负载均衡
    String url="http://user-service/user/"+id;

    return restTemplate.getForObject(url,String.class);
}

最后 再编写一个处理方法即可:

// 对全类的降级失败方法
public String defaultFallback()
{
    
    
    return "访问人数过多,请稍候重试。";
}

测试:
在这里插入图片描述

超时时长的配置:

Hystrix默认的超时时间为1秒 即1秒后访问依旧失败 则进行熔断

可以配置超时时长

application.yml:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            # Hystrix超时时长 默认为1秒 单位为毫秒
            timeoutInMilliseconds: 3000

2、服务熔断

在服务熔断中使用的熔断器也叫断路器 其英文单词为Circuit Breaker
熔断机制与电路熔断原理类似 若电路发生短路的时候能立刻熔断电路 避免发生灾难

在分布式系统中应用服务熔断后 服务调用方可以自己进行判断哪些服务反应慢或存在大量超时 可以针对这些服务进行主动熔断 以防止整个系统被拖垮

Hystrix的服务熔断机制可以实现弹性容错:当服务请求情况好转之后可以自动重连

通过断路的方式将后续请求直接拒绝 一段时间 (默认为5秒) 之后允许部分请求通过 若调用成功则回到断路器关闭状态 否则继续打开 拒绝请求的服务

下图为Hystrix的熔断机制模型:

  • Closed:关闭状态(断路器关闭) 此时所有请求都可正常访问
  • Open:打开状态(断路器打开) 所有请求都会被降级
    Hystrix会对请求情况计数 当一定时间内失败请求百分比达到阈值 则触发熔断 断路器会完全打开
    默认失败比例的阈值是50% 请求次数最少不低于20次
  • Half Open:半开状态 该状态不是永久的 断路器打开后会进入休眠时间(默认为5S)
    随后断路器会自动进入半开状态 此时会释放部分请求通过 若这些请求都是健康的 则会关闭断路器 否则继续保持打开 再次进行休眠计时
    在这里插入图片描述

服务熔断的配置:

在服务消费端进行配置

application.yml:

hystrix:
  command:
    default:
      circuitBreaker:
        # 触发熔断错误的比例阈值 默认值为50%
        errorThresholdPercentage: 50
        # 熔断后的休眠时长 默认为5秒 单位为毫秒
        sleepWindowInMilliseconds: 10000
        # 熔断触发最小请求次数 默认为20
        requestVolumeThreshold: 10

猜你喜欢

转载自blog.csdn.net/Piconjo/article/details/108713631
今日推荐