Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控)
我们平常在微服务项目中常会遇到这么一个问题,多个服务之间在调用时,如果其中一个服务由于网络问题挂了,那么服务的调用就会崩溃,那么我们在真实项目中是如何解决一个服务出现故障,又不影响其他服务的正常运行呢,那就是我们今天学习的Hystrix服务熔断器机制
1、什么是Hystrix?
- 1.1、Hystrix概念
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能够保证在一个依赖中出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
断路器
相当于一种开关控制
,通过断路器的故障监控
(保险丝),向调用方返回一个服务于其的、可处理的备用响应方案,而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩,可以防止服务雪崩
。
- 1.2、Hystrix能干嘛?
服务降级、服务熔断、服务限流、接近实时的监控等
- 1.3、图解服务调用时Hystrix的用途
在分布式系统中,应用程序可以多级连续调用服务,当其中一个服务由于某种原因挂了,就会产生服务雪崩
的情况,那么应用程序整个就会一直等待导致瘫痪,有了Hystrix服务熔灾
之后,当某一个服务挂了之后,服务会调用一个备用的服务,备用的服务返回一些提示错误的消息,不至于像以前直接整个应用程序产生雪崩效应
,不会导致整个服务失败,避免出现服务故障,
Hystrix官网查看具体架构图:github.com/Netflix/Hys…
2、服务熔断
- 2.1 服务熔断是什么?
熔断机制
是对雪崩效应
的一种微服务链路保护机制
springcloud中熔断机制通过Hystrix实现,Hystrix会监控微服务调用的状况,当5秒内20次调用失败就会启动熔断机制
,熔断机制的注解是@HystrixCommand
原理:熔断该节点微服务的调用,快速返回错误的响应信息
3、Hystrix服务熔断怎么实现?
第一步:重新创建一个服务提供者的服务(复制之前做过的8001端口的服务提供者即可)
第二步:pom文件中导入Hystrix依赖
<!--配置Hystrix依赖--><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端口),测试发现某个服务失败时,出现备用方法返回的错误信息,不会导致整个应用程序失败。
第七步:常规测试
依次开启集群(多个服务注册中心)、服务提供者(没有了熔断机制的服务提供者,直接返回异常)、服务消费者(80端口),测试发现某个服务失败时,出现导致整个应用程序失败的界面。
最后说一个配置:当我们在服务状态栏想显示我们的ip地址,而不是显示localhost,可以在application.yml中配置prefer-ip-address: true
,这样配置了之后,我们就可以看到不在一台电脑上操作的服务ip地址了。
prefer-ip-address: true# true 可以显示服务的ip,而不是显示localhost
4、服务降级
- 1、什么是服务降级
服务降级是指 当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。
资源有限,而请求是无限的。如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证核心功能服务的可用性,都要对某些服务降级处理。比如当双11活动时,把交易无关的服务统统降级,如查看蚂蚁深林,查看历史订单等等。
服务降级主要用于什么场景呢?当整个微服务架构整体的负载超出了预设的上限阈值或即将到来的流量预计将会超过预设的阈值时,为了保证重要或基本的服务能正常运行,可以将一些 不重要 或 不紧急 的服务或任务进行服务的 延迟使用 或 暂停使用。
- 2、图解说明服务降级
当在高并发情况下一个服务器有多个请求时,其他服务器请求不繁忙时,可以采用服务降级处理,暂时将其余不繁忙的服务关闭,等资源有剩余时,可开启其余的服务。
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) {
returnfalse;
}
};
}
}
- 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)之后,服务消费者去访问,发现返回友好错误提示页面,不会返回空或者异常,用户的体验度提升了。
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,可以看到服务已经注册进来了
访问localhost:9001/hystrix,可以看到默认的监控主界面(🐖界面)
打开http://localhost:8001/dept/get/1
服务提供方,测试数据是否拿到
打开http://localhost/hystrix.stream
,查看是否ping数据
填写将要监控的页面url:http://localhost:8001/actuator/hystrix.stream
,时间和标题默认即可,即可进入监控界面
进入监控界面之后,我们通过url:http://localhost:8001/dept/get/2
不断发送请求,可以发现监控页面出现圆圈变大,心跳波动明显等,它可以监控我们的请求信息。
7、监控页面各个部分的含义
- 一实心圆
圆的颜色代表了健康程度:绿色<黄色<橙色<红色, 绿色代表最健康安全,红色表示高危
圆的大小根据实例请求流量变化发生变化,流量越大,圆越大,可以在故障实例和高压力实例
场景中使用
- 一线
曲线:用来记录2分钟内流量的相对变化,通过它来观察流量的上升和下降趋势
- 6种颜色
绿色:成功数
蓝色:熔断数
淡蓝色:错误请求数
橙黄色:超时数
紫色:线程池拒绝数
橙色:失败/异常数
百分比:最近10s内错误百分比
Host:0.1/s: 服务请求频率
Circuit Closed: 断路状态
8、服务熔断、服务降级、DashBoard流监控
服务熔断和服务降级的区别:
触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始)
实现方式不太一样,服务降级具有代码侵入性(由控制器完成/或自动降级),熔断一般称为自我熔断。
限流:限制并发的请求访问量,超过阈值则拒绝;
降级:服务分优先级,牺牲非核心服务(不可用),保证核心服务稳定;从整体负荷考虑;
熔断:依赖的下游服务故障触发熔断,避免引发本系统崩溃;系统自动执行和恢复
9、回顾Springcloud微服务架构图
现在我们已经学习了红色部分得到内容了,包括Eureka服务注册与发现中心
、Ribbon客户端负载均衡
、Feign基于远程接口实现的负载均衡
、Hystrix服务熔断、服务降级、Dashboard流监控
等,接下来我们该学API网关了,接下来我们来学Zuul组件
吧!
好了,今天我们介绍了Hystrix服务熔断、服务降级、Dashboard流监控等,接下来我们要学习有关API网关路由的Zuul组件了,期待我们下篇博客吧!记得点赞👍+关注哦!小红心♥走起来!!!
以上是 Springcloud学习之路五(Hystrix服务熔断、服务降级、Dashboard流监控) 的全部内容, 来源链接: utcz.com/a/26173.html