Hystrix服务熔断
个人中心:学习日记的博客
前情提要:
什么是服务熔断,粗糙解释:我们知道一个系统存在很多微服务,而微服务与微服务之间又会存在相互调用,比如依赖关系A—>C—–B—–>D,如果B或者C一旦崩溃,那这条服务链就断了,C崩溃了,B和D的微服务也使用不了了,这就是服务雪崩,雪崩是离不开一个雪花的,所以这就需要服务熔断是一种保护机制,而可以熔断也可以降级相当于去掉改依赖节点而使其他微服务还可以正常使用,大致就是这么个意思吧。
看精细解释:
熔断机制是赌赢雪崩效应的一种微服务链路保护机制。
当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阀值缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是:@HystrixCommand
。
服务熔断解决如下问题:
- 当所依赖的对象不稳定时,能够起到快速失败的目的;
- 快速失败后,能够根据一定的算法动态试探所依赖对象是否恢复。
快速上手
我们新建一个有熔断机制的8004服务,把8001的服务大致复制下,老步骤
1、导入依赖
<dependencies>
<dependency>
<groupId>com.xuexi</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--Eureka依赖-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.0.0</version>
</dependency>
<!--完善监控信息-->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--hystrix-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
</dependencies>
2、编写配置,代码
把8001的代码复制了一下,然后修改了下启动类和端口
这里我们修改下controller中的代码,当服务异常时,我们也要进行返回信息处理,进行熔断
@HystrixCommand(fallbackMethod = "getNull") //当该服务异常时,调用异常备用服务
@GetMapping("/account/get/{id}")
public Account get(@PathVariable("id") long id){
Account byId = accountService.getById(id);
if (byId==null){
System.out.println("错误");
//定义一个异常
throw new RuntimeException("用户不存在");
}
return byId;
}
//失败回调方法
public Account getNull(@PathVariable("id") long id){
System.out.println("调用失败回调方法");
return new Account().setAccountId(id).setAccountName("null").setAccountPwd("null");
}
这里注解里面方法很多点进去就可以看下
3、开启功能
测试,我们启动一个注册中心7001,然后把hystrix这个服务开启,启动80去访问测试下,注册中心启动完成
通过80访问
这里我们差一个没有的id用户,触发异常看下什么效果
打印的就是我们进行服务熔断失败回调方法的信息,这就是服务熔断。
服务降级
那什么是服务降级呢?其实跟熔断差不多,熔断是个别服务的错误回调,那降级就是对一整个服务的取消,服务降级都是概念意思是当当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理,或换种简单的方式处理,从而释放服务器资源以保证核心业务正常运作或高效运作。说白了,就是尽可能的把系统资源让给优先级高的服务。
就好比我们平常在报名四六级的时候,我们知道很卡对不对,但是卡的刚刚好对不对,我们回到这个想法,报名当天是不是信息不需要修改,我们只需要报名就可以,所以你就会发现,其他设置可能不是很卡,或者直接不能用,而这个时候报名的人更多,我们就需要把报名的服务资源扩大,而关闭一些其他的服务,比如订单服务是不是一直在新增啊,那相应的修改服务我们就可以降级,也就是暂时关闭这个服务。
我理解这个更多的是人为,多说无益直接上代码
1、导入依赖
<!--hystrix-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
2、编写配置代码
我们在api服务层新建一个类,然后继承
package com.xuexi.service;
import com.xuexi.pojo.Account;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class AccountClientServiceFallbackFactory implements FallbackFactory{
@Override
public Object create(Throwable cause) {
return new AccountClientService() {
@Override
public List<Account> getAll() {
return null; // 其实这里应该返回一个R对象然后meassge是这样的
// "该服务被降级暂时停止访问,回复时间大致晚八点"
// 这里是能返回null了
}
};
}
}
因为服务降级存在在客户端,我们是不让客户去访问而不是去请求服务端拒绝,这个需要feign我们到feign80端口中,我们加一个配置,开启服务降级,其实也就是开启功能
3、开启功能,测试
我们把7001注册中心打开,然后把有熔断的服务打开8004,再打开这个服务降级的客户端,看下效果。
打开成功,并且服务注册了进去
80正常访问拿到数据
我们把8004服务给关闭,这时候手动将服务降级,然后我们再看下效果
什么都没有了,因为我们后台访问的返回的是null,如果平常服务崩溃的话,肯定是报错,因为只有这一个方法重写所以效果展示并不友好,而且其实应该是有一个统一响应,比如{code:200,data{},message:”消息”}这样的,因为前面例子没做好,所以讲究一下吧
为了证明是调用了服务降级的方法,我们这里加一个输出,build一下,我们访问看下
访问还是空的,因为返回null嘛,但是看控制台,对不对,这就是控制服务端的服务降级,然后不访问注册中心的服务,注册中心服务一但降级处理,这里返回响应。
Dashboard流监控
看名字就知道一个监控中心,监控客户端请求的,所以我们新建一个模块9001
1、导入依赖
<dependencies>
<dependency>
<groupId>com.xuexi</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--Eureka依赖-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.0.0</version>
</dependency>
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<!--hystrix-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix-dashboard -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
</dependencies>
2、编写配置
启动类
application编写端口号
3、开启功能,启动服务,我这里显示9001被系统服务占用,所以改成9002了,出来一个猪就对了
然后我们来配置下,可以监控服务信息。
我们到hystrix8004服务下添加一个servlet
//增加一个 Servlet
@Bean
public ServletRegistrationBean hystrixMetricsStreamServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
//访问该页面就是监控页面
registrationBean.addUrlMappings("/actuator/hystrix.stream");
return registrationBean;
}
这里你一定是有actuator的监控信息的,还记得之前我们这里的信息还得build一下,我们先不build尝试下
测试—–+错误调试
开启注册中心7001,然后开启8004有熔断机制的服务,然后使用开启80端进行访问测试,再打开9002监控,看下效果
访问服务,访问成功
我们进入9002监控中心,然后填写以下信息,http://localhost:8004/actuator/hystrix.stream
进行检测,然后发现失败
刚开始我以为是这个info这个没弄上,但是好像不是,其实应该不是,或者不是
我们需要在监控中心添加一个application.yml添加一个这样的配置
hystrix:
dashboard:
proxy-stream-allow-list: "*"
然后再启动,监控中心一直是loading,我这里就直接去访问了http://laptop-d5easg67:8004/actuator/hystrix.stream这个,然后一直是空的ping,一直在请求,但是返回一直是空;
这里看到人家说,你得先请求一次,然后有了数据,它再ping就有数据,然后我就请求了很多次,再ping也还是空,重点来了啊,这里根本没有客户端什么事,也就是没有80端口什么是,不是用80去请求,而是服务端直接请求,用http://laptop-d5easg67:8004/account/get/1去请求,才可以,然后有数据了,这样的,所以这里根本没有80端口什么是,重点:没有80端口什么事
然后我们重新进去监控中心,ok,成功
那监控中心是干什么的,这里请求几下数据试试,肯定是监控的呀
很简单吧,都能看懂,这里是具体参数
小结
都看到这里了还不赶紧三连关注不迷路,更多内容持续输出中,bye~