转载

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

我们平常在微服务项目中常会遇到这么一个问题,多个服务之间在调用时,如果其中一个服务由于网络问题挂了,那么服务的调用就会崩溃,那么我们在真实项目中是如何解决一个服务出现故障,又不影响其他服务的正常运行呢,那就是我们今天学习的Hystrix服务熔断器机制

1、什么是Hystrix?

  • 1.1、Hystrix概念

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能够保证在一个依赖中出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

断路器 相当于一种 开关控制 ,通过断路器的 故障监控 (保险丝), 向调用方返回一个服务于其的、可处理的备用响应方案,而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩,可以防止服务雪崩

  • 1.2、Hystrix能干嘛?

服务降级、服务熔断、服务限流、接近实时的监控等

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
  • 1.3、图解服务调用时Hystrix的用途

在分布式系统中,应用程序可以多级连续调用服务,当其中一个服务由于某种原因挂了,就会产生 服务雪崩 的情况,那么应用程序整个就会一直等待导致瘫痪,有了 Hystrix服务熔灾 之后,当某一个服务挂了之后,服务会调用一个备用的服务,备用的服务返回一些提示错误的消息,不至于像以前直接整个应用程序产生 雪崩效应 ,不会导致整个服务失败,避免出现服务故障,

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
Hystrix官网查看具体架构图: github.com/Netflix/Hys…

2、服务熔断

  • 2.1 服务熔断是什么?

熔断机制 是对 雪崩效应 的一种 微服务链路保护机制

springcloud中熔断机制通过Hystrix实现,Hystrix会监控微服务调用的状况,当5秒内20次调用失败就会启动 熔断机制 ,熔断机制的注解是 @HystrixCommand

原理:熔断该节点微服务的调用,快速返回错误的响应信息

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

3、Hystrix服务熔断怎么实现?

第一步:重新创建一个服务提供者的服务(复制之前做过的8001端口的服务提供者即可)

第二步:pom文件中导入Hystrix依赖

<!--配置Hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.3.RELEASE</version>
        </dependency>
复制代码

第三步:编写配置文件application.yml

server:
  port: 8080
# mybatis 配置
mybatis:
  type-aliases-package: com.baoji.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml  #config-location  为mybatis配置文件
  mapper-locations: classpath:mybatis/mapper/*.xml  #mapper-locations  为mapper配置
  #spring配置
spring:
  application:
    name: springcloud-provider
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/xxx?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
    username: xxx
    password: xxx
#Eureka的配置  服务注册到哪里  和注册中心服务的路径一样
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: springcloud-provider-dept-hystrix8001  # 修改eureka上的默认描述信息
    prefer-ip-address: true  # true 可以显示服务的ip,而不是显示localhost
#info信息
info:
  app.name: linchi-springcloud
  company.name: com.baoji
复制代码

第四步:编写功能(controller中写功能)

使用Feign面向接口调用风格,属性注入 service层 ,调用方法即可

熔断机制核心代码原理实现:

1、编写根据id查询员工对象方法,我们平常的做法是获得一个对象之后,判断该对象是否为null,如果为null,抛出错误异常,捕获该异常即可,但是在微服务中这是行不通的。

2、我们要编写一个备选方案的方法,直接return该对象,使用链式编程将要返回的错误信息进行输出,最好使用 @HystrixCommand(fallbackMethod = "hystrixGet") 注解,这个注解是当服务出现故障时,会调用下面的备选方案处理,返回一个提示信息的对象,调用的本之还是这个请求。

package com.baoji.springcloud.controller;

import com.baoji.springcloud.pojo.Dept;
import com.baoji.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//提高ResultFul服务
@RestController
public class DeptController {
    //属性注入service层
    @Autowired
    private DeptService deptService;

    @GetMapping("/dept/get/{id}")
    @HystrixCommand(fallbackMethod = "hystrixGet")  //当服务出现故障时,会调用下面的备选方法处理,返回一个提示信息的对象,调用的本之还是这个请求
    public Dept get(@PathVariable("id") Long id){
        Dept dept = deptService.getDeptById(id);
        if(dept == null){
            throw new RuntimeException("id=>"+id+",不存在该用户,或者用户信息不存在!");
        }
        return dept;
    }

    //备选方案
    public Dept hystrixGet(@PathVariable("id") Long id){
        return new Dept().setDeptno(id)
                .setDeptname("id=>"+id+",没有对应的信息,null->@Hystrix")
                .setDb_source("no this database in mysql");
    }
}
复制代码

第五步:在主启动类上添加 @EnableCircuitBreaker 注解, 添加对熔断器的支持。

启动类代码如下:

package com.baoji.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient  //把客户端服务启动之后,将服务自动注册到服务端
@EnableDiscoveryClient  //服务发现,获取微服务的一些信息
@EnableCircuitBreaker  //添加对熔断器的支持
public class DeptProvidre_hystrix_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvidre_hystrix_8001.class,args);
    }
}
复制代码

第六步:Hystrix熔断机制测试

依次开启集群(多个服务注册中心)、服务提供者(开启了熔断机制的服务提供者,调用备用方法返回错误信息)、服务消费者(80端口),测试发现某个服务失败时,出现备用方法返回的错误信息,不会导致整个应用程序失败。

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
第七步:常规测试 依次开启集群(多个服务注册中心)、服务提供者(没有了熔断机制的服务提供者,直接返回异常)、服务消费者(80端口),测试发现某个服务失败时,出现导致整个应用程序失败的界面。
Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
最后说一个配置:当我们在服务状态栏想显示我们的ip地址,而不是显示localhost,可以在application.yml中配置 prefer-ip-address: true ,这样配置了之后,我们就可以看到不在一台电脑上操作的服务ip地址了。
prefer-ip-address: true  # true 可以显示服务的ip,而不是显示localhost
复制代码
Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

4、服务降级

  • 1、什么是服务降级

服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。 资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证核心功能服务的可用性,都要对某些服务降级处理。比如当双11活动时,把交易无关的服务统统降级,如查看蚂蚁深林,查看历史订单等等。

服务降级主要用于什么场景呢?当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,可以将一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。

  • 2、图解说明服务降级

当在高并发情况下一个服务器有多个请求时,其他服务器请求不繁忙时,可以采用服务降级处理,暂时将其余不繁忙的服务关闭,等资源有剩余时,可开启其余的服务。

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

5、服务降级怎么使用?

  • 1、在客户端springcloud-api中编写服务降级操作

让该类实现FallbackFactory接口,返回要返回给服务接口的实例,输出错误信息,说明使用了服务降级处理,该服务不可用的友好提示。

package com.baoji.springcloud.service;

import com.baoji.springcloud.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class DeptClientServiceFailBackFactory implements FallbackFactory {
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            public Dept quaryById(Long id) {
                return new Dept().setDeptno(id)
                        .setDeptname("id"+id+"没有对应的信息,客户端提供了降级的信息,这个服务已经被关闭!")
                        .setDb_source("没有数据");
            }

            public List<Dept> queryAll() {
                return null;
            }

            public boolean addDept(Dept dept) {
                return false;
            }
        };
    }
}
复制代码
  • 2、在业务接口中调用服务降级操作类

在该业务接口中 @FeignClient 注解中使用 fallbackFactory=DeptClientServiceFailBackFactory.class 属性即可,说明该业务接口调用出现错误时服务降级操作的类。

package com.baoji.springcloud.service;

import com.baoji.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Component  //此注解是将此接口注入到spring中
//可以被其他服务直接调用,通过客户端去找springcloud-provider服务名,进行负载均衡
@FeignClient(value = "springcloud-provider",fallbackFactory = DeptClientServiceFailBackFactory.class)  //fallbackFactory 表示该业务服务失败时调用失败业务服务的服务降级操作
public interface DeptClientService {
    @GetMapping("/dept/get/{id}")
    public Dept quaryById(@PathVariable("id") Long id);
    @GetMapping("/dept/list")
    public List<Dept> queryAll();
    @PostMapping("/dept/add")
    public boolean addDept(Dept dept);
}
复制代码
  • 3、启用服务降级操作

在feign服务消费者中添加开启降级配置,使用了该配置才能将feign和hystrix同时使用

# 开启降级  feign和hystrix设置此配置时,feign和hystrix才能同时使用
feign:
  hystrix:
    enabled: true
复制代码
  • 4、测试服务降级

开启注册中心服务(7001)、开启服务提供者(8001)、开启服务消费者(feign-80)后,访问查询某个部门,正常显示,当关闭了这个服务提供者服务(8001)之后,服务消费者去访问,发现返回友好错误提示页面,不会返回空或者异常,用户的体验度提升了。

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

6、服务限流(Dashboard流监控)怎么用

限流:限制并发的请求访问量,超过阈值则拒绝;

1、编写一个监控页面

第一步:创建一个Model(springcloud-consume-hystrix-dashboard),添加 Hystrix 依赖和 hystrix-dashboard 监控页面依赖

<!--Hystrix服务熔断与降级-->
<?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>springcloud</artifactId>
        <groupId>com.baoji</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consume-hystrix-dashboard</artifactId>
    <!--消费者-->
    <dependencies>
        <!--Hystrix服务熔断与降级-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--Hystrix监控页面-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--Feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--给消费者引入Ribbon依赖。让消费者从注册中心获取到服务列表的地址-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--给消费者加入Eureka客户端,方便消费者在注册中心发现更多服务-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.3.RELEASE</version>
        </dependency>
        <!--实体类+web-->
        <dependency>
            <groupId>com.baoji</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
复制代码

2、第二步:在resources下编写application.yml中端口为9001

server:
  port: 9001
复制代码

3、第三步:编写启动类

使用 @EnableHystrixDashboard 注解开启监控页面功能

package com.baoji.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@SpringBootApplication
@EnableHystrixDashboard  //开启监控页面功能
public class DeptConsumeDashboard_9001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumeDashboard_9001.class,args);
    }
}
复制代码
  • 4、在之前编写的具有服务熔断与降级的服务生产者类中修改配置

第四步:此服务注册进注册中心要被监控必须要有 spring-boot-starter-actuator 完善监控依赖,再添加 spring-cloud-starter-hystri 熔断机制依赖

<!--actuator完善监控的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
 <!--配置Hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.3.RELEASE</version>
        </dependency>
复制代码

5、第五步:注入一个可以被监控的servlet,监控路径为 /actuator/hystrix.stream ,访问此url,该服务就可以被监控了。

package com.baoji.springcloud;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient  //把客户端服务启动之后,将服务自动注册到服务端
@EnableDiscoveryClient  //服务发现,获取微服务的一些信息
@EnableCircuitBreaker  //添加对熔断器的支持
public class DeptProvidre_hystrix_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvidre_hystrix_8001.class,args);
    }
    //注入一个可以被监控的servlet
    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        registrationBean.addUrlMappings("/actuator/hystrix.stream");  //添加访问的路径,访问/actuator/hystrix.stream监控的页面就可以被监控了
        return registrationBean;
    }}
复制代码

6、测试

依次打开服务注册中心(7001),监控页面(9001),服务提供者(Hystrix_8001),访问localhost/7001,可以看到服务已经注册进来了

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

访问localhost:9001/hystrix,可以看到默认的监控主界面(:pig2:界面)

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
打开 http://localhost:8001/dept/get/1

服务提供方,测试数据是否拿到

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
打开 http://localhost/hystrix.stream

,查看是否ping数据

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

填写将要监控的页面url: http://localhost:8001/actuator/hystrix.stream ,时间和标题默认即可,即可进入监控界面

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
进入监控界面之后,我们通过url: http://localhost:8001/dept/get/2

不断发送请求,可以发现监控页面出现圆圈变大,心跳波动明显等,它可以监控我们的请求信息。

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

7、监控页面各个部分的含义

  • 一实心圆

圆的颜色代表了健康程度:绿色<黄色<橙色<红色, 绿色代表最健康安全,红色表示高危

圆的大小根据实例请求流量变化发生变化,流量越大,圆越大,可以在 故障实例和高压力实例 场景中使用

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
  • 一线

曲线:用来记录2分钟内流量的相对变化,通过它来观察流量的上升和下降趋势

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
  • 6种颜色

绿色: 成功数

蓝色: 熔断数

淡蓝色: 错误请求数

橙黄色: 超时数

紫色: 线程池拒绝数

橙色: 失败/异常数

百分比: 最近10s内错误百分比

Host:0.1/s: 服务请求频率

Circuit Closed: 断路状态

Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)

8、服务熔断、服务降级、DashBoard流监控

服务熔断和服务降级的区别:

触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;

管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)

实现方式不太一样,服务降级具有代码侵入性(由控制器完成/或自动降级),熔断一般称为自我熔断。

限流:限制并发的请求访问量,超过阈值则拒绝;

降级:服务分优先级,牺牲非核心服务(不可用),保证核心服务稳定;从整体负荷考虑;

熔断:依赖的下游服务故障触发熔断,避免引发本系统崩溃;系统自动执行和恢复

原文  https://juejin.im/post/5eeac66be51d4573cb313aa8
正文到此结束
Loading...