晓我课堂

Spring Cloud系列之Hystrix

2021-12-28  本文已影响0人  wavefreely

Spring Cloud系列之Eureka
Spring Cloud系列之配置中心Config
Spring Cloud系列之gateway
Spring Cloud系列之Feign
Spring Cloud系列之Hystrix
Spring Cloud系列之链路追踪

在介绍Hystrix之前我们先来了解微服务中的雪崩效应

雪崩效应

雪崩效应.png

以上图为例,当我们的用户微服务发生异常时,响应时间过长或者服务不可用的时候,当用户访问订单服务的时候,程序的执行可能就一直卡在订单服务访问用户微服务,实际上其他微服务都没有任何问题,但是因为用户微服务出了问题,导致订单服务响应时间过长,大量的请求阻塞,线程没有释放,导致服务器资源耗尽,最终导致所有服务都不可用,造成整个系统瘫痪,这就形成了雪崩效应。实际上就是其中一个微服务出了问题,导致所有的都不可用。

就好比一个汽车生产线,生产不同的汽车,需要使用不同的零件,如果某个零件因为种种原因无法使用,那么就会造成整台车无法装配,陷入等待零件的状态,直到零件到位,才能继续组装。 此时如果有很多个车型都需要这个零件,那么整个工厂都将陷入等待的状态,导致所有生产都陷入瘫痪。一个零件的波及范围不断扩大

雪崩产生原因

在我们实际开发过程中造成雪崩的原因有很多:

雪崩效应的解决方案

Hystrix简介

Hystrix 中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。本文所说的Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。为了实现容错和自我保护,下面我们看看Hystrix如何设计和实现的

Hystrix解决雪崩问题的手段包括:

Hystrix工作流程

hystrix工作流程.png

文字总结下:

入门

<!--hystrix依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
# 配置熔断策略:
hystrix:
  command:
    default:
      #断路器配置
      circuitBreaker:
        errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
        sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒
        requestVolumeThreshold: 10 # 熔断触发最小请求次数,默认值是20
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 熔断超时设置,默认为1秒
/**
 * @Description:
 * @author: dy
 */
//开启feign客户端功能 basePackages指定要扫描的feignClient类所在包路径
@EnableFeignClients(basePackages = {"com.dy.user.client"})
//开启Eureka客户端发现功能
@EnableDiscoveryClient
//开启熔断器功能
@EnableCircuitBreaker
@SpringBootApplication(scanBasePackages = {
        //client指定了fallback,这里要把所有hystrix的fallback注入容器中
        "com.dy.user.fallback",
        //指定了scanBasePackages要把我们本身的bean注入到容器中 
        "com.dy.userapi"
})
public class UserApiApplication {

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

}
/**
 * @Description:
 * @author: dy
 */
@Slf4j
@RestController
@RequestMapping(UserClient.MAPPING)
public class UserResource implements UserClient {

    @Autowired
    private AppInfo appinfo;
    @Value("${server.port}")
    private Integer port;

    @Override
    public String getUserId() {
        try {
            //模拟超时
            Thread.sleep(10000);
        }catch (Exception e){
        }
        log.info("==============请求来了===============");
        return "======111111222>>"+appinfo.getAppId()+"====port:"+port;
    }
}
/**
 * @Description:
 * @author: dy
 */
@Slf4j
@RestController
public class UserController implements UserApi {

    @Autowired
    private UserClient userClient;

    @Override
    public String getUserInfo() {
        log.info("==========滴滴========");
        return userClient.getUserId();
    }

    @Override
    //指定降级缺省值执行方法
    @HystrixCommand(fallbackMethod = "getDefaultUserId")
    public String testHystrix() {
        return userClient.getUserId();
    }

    public String getDefaultUserId(){
        return "默认值";
    }
}

执行结果:


hystrix降级执行结果.jpg

我们也可以模拟hystrix的熔断功能,看到达我们设置的阈值是否服务熔断了,也可以得到相同的执行结果

在我们实际开发过程中一般都是feign+hystrix结合使用的!

Hystrix资源隔离(舱壁模式)

资源隔离的原因

在一个分布式系统中,服务之间都是相互调用的,例如,我们容器(Tomcat)配置的线程个数为 1000,服务 A-服务 R,其中服务 I 的并发量非常的大,需要 500 个线程来执行,此时,服务 I 又挂了,那么这 500 个线程很可能就夯死了,那么剩下的服务,总共可用的线程为 500 个,随着并发量的增大,剩余服务挂掉的风险就会越来越大,最后导致整个系统的所有服务都不可用,直到系统宕机。以上就是服务的雪崩效应。

Hystrix 就是用来做资源隔离的,比如说,当客户端向服务端发送请求时,给服务 I 分配了 10 个线程,只要超过了这个并发量就走降级服务,就算服务 I 挂了,最多也就导致服务 I 不可用,容器的 10 个线程不可用了,但是不会影响系统中的其他服务。

实现方式

Hystrix实现资源隔离的方式有两种:

Hystrix Dashboard+Turbine

当我们的应用程序使用了hystrix后,每个具体的hystrixCommand命令执行后都会产生一堆的监控数据,比如:成功数,失败数,超时数以及与之关联的线程池信息等。既然有了这些监控数据数据,那么我们应该如何进行查看呢?答案当然是通过hystrix dashboard 来进行查看,但hystrix dashboard只能查看单个应用内的服务信息,这个显然是不够的,因此我们需要一个能够将系统内多个服务的监控数据汇总到hystrix dashboard上,这个时候就应该使用turbine

仪表盘项目需要单独的创建

新建hystrix-dashboard的module

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dy-springcloud</artifactId>
        <groupId>com.dy</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dy.dashboard</groupId>
    <artifactId>hystrix-dashboard</artifactId>

    <dependencies>


        <!--eureka-client依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- hystrix dashboard仪表盘依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

        <!-- turbine依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
        </dependency>

    </dependencies>

</project>
server:
  port: 10006
spring:
  application:
    name: hystrix-dashboard

#eureka 参数配置
eureka:
  # 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
  instance:
    # 获取实例的ip地址
    prefer-ip-address: true
    #  与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
    hostname: localhost
    #  eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒
    lease-renewal-interval-in-seconds: 10
    #  Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
    lease-expiration-duration-in-seconds: 30
  client:
    # 注册自己
    register-with-eureka: true
    # 不拉取服务
    fetch-registry: true
    # 配置服务地址
    service-url:
      # eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址  ,如果是多台eureka server 地址以逗号隔开
      defaultZone: http://127.0.0.1:10001/eureka

#turbine配置
turbine:
  #appconfig配置需要聚合的服务信息,比如这里我们需要聚合user-api的监控数据
  #如果需要聚合多个服务,那么可以用英文逗号进行分隔
  app-config: USER-API
  cluster-name-expression: "'default'"  #集群默认名称
/**
 * @Description:
 * @author: dy
 */
//开启服务注册发现功能
@EnableDiscoveryClient
//开启仪表盘功能
@EnableHystrixDashboard
//开启turbine聚合功能
@EnableTurbine
@SpringBootApplication
public class DashboardApplication {

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

}

运行项目打开url:http://localhost:10006/hystrix进入监控首页:

hystrix-dashboard-page1.png
输入我们要监控的服务信息,就可以看到我们的监控详情页面了: hystrix-dashboard-page2.png
上一篇 下一篇

猜你喜欢

热点阅读