SpringCloud(四)——Hystrix
本篇笔记针对服务雪崩、熔断以及降级的概念进行简单阐述,同时针对这三个概念进行对应的代码处理和实现。
文章目录
概述
服务雪崩
服务雪崩的概念在很久之前就已经出现,举个**“栗子”**:
在上图中,我们可以看出:A发送请求给B,B处理请求后交给C,而C在处理结束后将相应数据返回给B,B接收到响应数据后再返回给A。以上,该业务执行结束。
如果我们的C服务在处理请求时出现问题(比如:无法解决的异常但并没有使程序结束、死循环等问题),导致我们的C无法及时返回响应数据给B,而B在在该业务执行的过程中一直等待C的响应,以此类推,最终导致这个服务链崩溃。
服务熔断
服务熔断是一种解决服务雪崩的一种方案,如果服务出现崩溃很有可能导致连锁反应,最终导致整个系统出现不可挽回的损失。
在程序出现服务雪崩的先兆的时候我们就会断掉该服务,使该服务不可用。即多次出现请求失败或者响应失败的时候将出现问题的服务断开,禁止请求该服务,同时对请求该服务的线程快速响应一个数据,表示该服务暂时不可用等信息。
服务熔断在服务提供方和服务调用方都可以设置且都要设置,这样可以更快的响应问所在。
服务降级
服务降级从某种意义上将可以理解为另一种服务熔断,但是他不是根据出问题的服务进行熔断操作,而是一种针对核心服务的保护机制。
比如:银行的网银系统主要目的是账户与账户之间资金的转入转出,而其他的服务(比如搜索、广告、娱乐小程序等)就不属于保护之中。即通过业务重要性对该系统所有的服务进行分级,如果出现系统实时吞吐量过大导致对核心服务产生影响,就会对一些不重要的非核心服务实施断开处理,从而保证核心服务不会出现问题。
再说的通俗一点就是我们使用的电脑配置过低时,打开多个游戏会出现系统卡顿,当严重的时候会出现死机的情况,然后系统会将游戏等不重要的程序强制关闭,保证系统核心服务的正常运行。
服务雪崩处理
先介绍一个已经被弃用的组件(官方弃用不代表公司不用,没上过班的同学可能想不到老系统改架构有多难,以后工作维护老系统会有用的)。
Hystrix
服务被调用方
- 引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
- 入口类加注解:
@EnableHystrix
public class HystrixApplication {
public static void main(Stirng[] args){
SpringApplication.run(HystrixApplication.class,args);
}
}
- 定义出现问题后的快速响应:
@GetMapping("/test")
// 该注解表示如果此方法在调用过程中出现了问题,则会执行默认的方法来进行快速响应
@HystrixCommand(defaultFallback = "defaultFallBack")
String test(@RequestParam("id") Integer id){
if (id <= 0){
throw new RuntimeException("无效ID");
}
return "test is success";
}
public String defaultFallBack(){
return "当前服务过于火爆,已经熔断";
}
以上就是Hystrix的简单使用。服务熔断的机制是在短时间内请求失败多次会将该服务进行熔断,从官方和源码中得知,在10s
内出现20次失败请求或者百分之50以上的错误请求会出现服务熔断,在熔断5s
后会半开启服务,允许一个请求通过,如果请求依旧失败则表示该服务存在问题,将会继续关闭该服务。
服务请求方
在上一篇笔记中我们记录了使用OpenFeign组件进行负载均衡的服务间调用,在这里我们可以继续使用该架构。
- 引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
OpenFeign
接口注解
// fallback 表示该接口中所有请求的方法的快速响应方法都由 TestClientFallBack 类中的实现的接口来实现
@FeignClient(value="TEST",fallback = TestClientFallBack.class)
public interface TestClient{
@GetMapping("/test")
public String test();
}
- 编辑Hystrix快速响应方法:
// 首先定义一个类,实现OpenFeign客户端接口
public class TestClientFallBack implements TestClient{
@GetMapping("/tets")
public String test(){
return "当前服务不可用!";
}
}
在调用服务的时候,如果因为对应的服务宕机则会出现其他意外情况。毕竟被调用的服务宕机后也不可能为调用方提供断路器的快速响应。所以在调用方定义该操作可以避免该情况,当对方服务宕机,该服务直接快速响应错误信息。
HystrixDashBoard(负载均衡仪表盘)
该组件的主要作用是检测系统中各项服务的状态,比如是否熔断,其他服务的请求是否成功(由于该组件官方已经废弃,所以制作简单介绍和说明)。
仪表盘的使用需要书写一个仪表盘的项目,按照正常的Springcloud项目来配置,在此不做赘述。
HystrixDashBoard配置
- 引入依赖
<!--hystrixdashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
- 书写配置
# 配置代理地址,在本地书写的仪表盘项目
hystrix.dashboard.proxy-stream-allow-list=localhost
# 该配置的文件类型为 properties ,如果是 yml类型的文件则 localhost 需要双引号
- 入口类加注解
// 开启当前仪表盘
@EnableHystrixDashboard
public class HystrixDashBoardApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixDashBoardApplication.class,args);
}
}
在此,我们的仪表盘服务已经部署完成,可以启动该项目来查看仪表盘的页面。我们可以通过在浏览器中访问以下路径查看界面。
localhost:${port}/hystrix
界面如下所示:
通过界面中的描述我们可以得知,如果想要在仪表盘中检测集群的状态,则需要使用https://turbine-hostname:port/turbine.stream
,但是一般使用检测单个服务的方式,即:https://hystrix-app:port/actuator/hystrix.stream
。
当然在现在还不能直接使用,需要被仪表盘检测的项目也需要进行一系列相关的配置才可以被发现。
被检测服务配置
- 引入依赖
需要被该仪表盘检测的服务必须使用Hystrix
组件,在此不做赘述。
- 书写配置(两种方式)
该仪表盘组件有一个Bug,我们很有可能在检测某个服务的时候出现无法找到服务组的错误。这个时候是因为我们没有将被检测服务指定为可以被检测或者没有放到仪表盘的指定检测组中。该问题暂时整理出两种解决办法,其底层原理相似:
- 书写配置类:
@Configuration
public class BeansConfig {
// 将被HystrixCommand注解修饰的控制器通过 addUrlMappings中传递给Hystrix,在这里可以定义路径
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
// 下面这条配置表示我们将通过那个路径访问到当前服务
// registrationBean.addUrlMappings("/actuator/hystrix.stream");
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
该配置类表示,将当前服务放入到对应的路径中(或者可以理解为:允许这条路径来获取当前服务的状态)。这样按照对应的检测路径就可以查看到对应的服务状态。
- 书写配置文件:
# 开启访问站点
management.endpoints.web.exposure.include=*
# 这种方式在当前版本默认访问路径不加 actuator。
该配置表示将该项目暴露出来,可以供所有人访问当前服务的状态。
这样就可以使用仪表盘来检测该服务。
总结
本篇笔记中记录了Hystrix的基本介绍和使用,同时在开篇的时候介绍了服务雪崩等相关的概念。再次重申,被官方弃用的组件不代表真的就没用了,由于技术更新迭代较快,且新技术需要时间去验证是否稳定,所以总会出现某些地区的项目或者公司出现技术断层(这个求您别杠,21年的时候我还见过使用SSM+JSP页面的单体项目开发工作)。
所以大家在学新技术的时候会用就行,多花一些时间探究原理和底层可以打好地基,以便于未来的发展。