Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力。本文所说的Hystrix是Netflix开源的一款容错框架,同样具有自我保护能力。

本文目录

一、Hystrix简介二、Hystrix的设计原则三、Hystrix的工作原理四、Ribbon中使用熔断器五、Feign中使用熔断器六、踩到的坑

一、Hystrix简介

Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性、容错性与局部应用的弹性,是一个实现了超时机制和断路器模式的工具类库。

二、Hystrix的设计原则

  • 防止任何单独的依赖耗尽资源(线程)
    过载立即切断并快速失败,防止排队
  • 尽可能提供回退以保护用户免受故障
  • 使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响
  • 通过近实时的指标,监控和告警,确保故障被及时发现
  • 通过动态修改配置属性,确保故障及时恢复
  • 防止整个依赖客户端执行失败,而不仅仅是网络通信

三、Hystrix的工作原理

  • 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行。
  • 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)。
  • 记录请求成功,失败,超时和线程拒绝。
  • 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求。
  • 请求失败,被拒绝,超时或熔断时执行降级逻辑。
  • 近实时地监控指标和配置的修改。

当使用Hystrix封装每个基础依赖项时,每个依赖项彼此隔离,受到延迟时发生饱和的资源的限制,并包含回退逻辑,该逻辑决定了在依赖项中发生任何类型的故障时做出什么响应。

四、Ribbon中使用熔断器

按照下面步骤改造之前的项目spring-cloud-consumer-ribbon

  1. pom.xml引入jar包
<!-- 整合hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
  1. 启动类上添加@EnableHystrix注解

在启动类上添加@EnableHystrix注解开启Hystrix的熔断器功能,改造后启动类如下:

@EnableHystrix //在启动类上添加@EnableHystrix注解开启Hystrix的熔断器功能。
@EnableEurekaClient
@SpringBootApplication
public class RibbonConsumerApplication {     //当添加@LoadBalanced注解,就代表启动Ribbon,进行负载均衡
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }     public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    } }
  1. 添加HystrixConsumerController

在需要有熔断机制的方法上添加 @HystrixCommand,属性fallbackMethod是熔断时返回的方法,编写完成后HystrixConsumerController.java代码如下:

/**
 * 消费者
 */
@Slf4j
@RestController
@RequestMapping("/hystrix/consumer")
public class HystrixConsumerController {     @Autowired
    private RestTemplate restTemplate;     /**
     * 调用 user微服务
     */
    @HystrixCommand(fallbackMethod = "getDefaultUser")
    @GetMapping("getUser")
    public String getUser(Integer id) {
        String url = "http://user-service/provider/getUser?id=" + id;
        return restTemplate.getForObject(url, String.class);
    }     public String getDefaultUser(Integer id) {
        System.out.println("熔断,默认回调函数");
        return "{\"id\":-1,\"name\":\"熔断用户\",\"password\":\"123456\"}";
    }
}
  1. 开始测试

代码编写之后,按顺序启动spring-cloud-eureka、spring-cloud-user-service和spring-cloud-consumer-ribbon,此时打开浏览器访问http://localhost:8082/hystrix/consumer/getUser?id=2,服务正常,截图如下:


服务正常截图

然后停服务spring-cloud-user-service,再次访问访问http://localhost:8082/hystrix/consumer/getUser?id=2,此时会触发熔断,截图如下:


触发熔断后截图

五、Feign中使用熔断器

Feign在整合到Spring Cloud时已经自带了hystrix模块,所以pom.xml中不需要额外引入feign依赖。

新建一个spring boot项目spring-cloud-consumer-fegin-hystrix,按照下面步骤操作。

  1. application.yml中开启熔断器
server:
  port: 8082 #服务端口
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:9001/eureka/
spring:
  application:
    name: fegin-hystrix-consumer feign:
      hystrix:
        # feign熔断器开关
        enabled: true
  1. 新建一个FeignClient接口

新建一个FeignClient接口UserFeginService并指定fallback,代码如下:

//表示"user-service"的服务,指定fallback
@FeignClient(value = "user-service", fallback = UserFeginFailBackImpl.class)
public interface UserFeginService {     @RequestMapping(value = "/provider/getUser")
    public String getUser(@RequestParam("id") Integer id);
}

@FeignClient注解参数说明:

  • name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现。

  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口。

  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码

  • path: 定义当前FeignClient的统一前缀,类似于注解到类上的@RequestMapping的功能

  1. 添加熔断处理类UserFeginFailBackImpl

代码如下:

@Slf4j
@Component
public class UserFeginFailBackImpl implements UserFeginService {     @Override
    public String getUser(Integer id) {
        log.info("熔断,默认回调函数");
        return "{\"id\":-1,\"name\":\"熔断用户\",\"msg\":\"请求异常,返回熔断用户!\"}";
    }
}
  1. 添加Controller

添加FeginHystrixController,用于调用user-service,代码如下:

@RestController
@RequestMapping("/hystrix/consumer")
public class FeginHystrixController {     @Autowired
    private UserFeginService userFeginService;     @GetMapping("/getUser")
    public String getUser(Integer id) {
        return userFeginService.getUser(id);
    }
}

5 开始测试

代码编写之后,按顺序启动spring-cloud-eureka、spring-cloud-user-service和spring-cloud-consumer-fegin-hystrix,此时打开浏览器访问http://localhost:8082/hystrix/consumer/getUser?id=2,服务正常,截图如下:


服务正常截图

然后停服务spring-cloud-user-service,再次访问访问http://localhost:8082/hystrix/consumer/getUser?id=2,此时会触发熔断,截图如下:


触发熔断后截图

六、踩到的坑

  1. hystrix的异常fallback method wasn't found

出现这个异常是因为指定的备用方法和原方法的参数个数或类型不同造成的,所以需要统一参数的类型和个数。

到此SpringCloud两种方式整合Hystrix的功能已经全部实现,有问题欢迎留言沟通哦!

完整源码地址: https://github.com/suisui2019/springboot-study

推荐阅读

1.SpringCloud系列-利用Feign实现声明式服务调用)
2.手把手带你利用Ribbon实现客户端的负载均》
3.SpringCloud搭建注册中心与服务注册
4.Spring Boot配置过滤器的两种方式!
5.编码神器Lombok,学会后开发效率至少提高一倍!


限时领取免费Java相关资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并发分布式、大数据、机器学习等技术。
关注下方公众号即可免费领取:

Java碎碎念公众号

SpringCloud系列-整合Hystrix的两种方式的更多相关文章

  1. SpringBoot整合Servlet的两种方式

    SpringBoot整合Servlet有两种方式: 1.通过注解扫描完成Servlet组件的注册: 2.通过方法完成Servlet组件的注册: 现在简单记录一下两种方式的实现 1.通过注解扫描完成Se ...

  2. SpringBoot从入门到精通二(SpringBoot整合myBatis的两种方式)

    前言 通过上一章的学习,我们已经对SpringBoot有简单的入门,接下来我们深入学习一下SpringBoot,我们知道任何一个网站的数据大多数都是动态的,也就是说数据是从数据库提取出来的,而非静态数 ...

  3. Spring Boot 整合 Shiro ,两种方式全总结!

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  4. 【SpringBoot】05.SpringBoot整合Listener的两种方式

    SpringBoot整合Listener的两种方式: 1.通过注解扫描完成Listener组件的注册 创建一个类实现ServletContextListener (具体实现哪个Listener根据情况 ...

  5. 【SpringBoot】03.SpringBoot整合Servlet的两种方式

    SpringBoot整合Servlet的两种方式: 1. 通过注解扫描完成Servlet组件注册 新建Servlet类继承HttpServlet 重写超类doGet方法 在该类使用注解@WebServ ...

  6. 服务容错保护断路器Hystrix之一:入门示例介绍(springcloud引入Hystrix的两种方式)

    限流知识<高可用服务设计之二:Rate limiting 限流与降级> 在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的 ...

  7. Spring整合Hibernate的两种方式

    在使用spring注解整合hibernate时出现"org.hibernate.MappingException: Unknown entity: com.ssh.entry.Product ...

  8. 【SpringBoot】04.SpringBoot整合Filter的两种方式

    SpringBoot整合Filter过滤器的两种方式: 1.通过扫描注解完成Filter组件注册 创建一个类,实现Filter接口,实现doFilter()方法 在该类使用注解@WebFilter,设 ...

  9. springboot整合mybatis的两种方式

    https://blog.csdn.net/qq_32719003/article/details/72123917 springboot通过java bean集成通用mapper的两种方式 前言:公 ...

随机推荐

  1. 第11讲-Java泛型和文件操作

    1.知识点 1.1.课程回顾 1.2.本章重点 1.2.1.泛型 1.2.2.文件操作 2.具体内容 2.1.Java泛型 2.1.1.为什么需要泛型 我们发现在List中,底层是Object[ ]数 ...

  2. android 多行 RadioButton的使用

    最近项目用到了多行RadioButton,随记录下. 先给出RadioButton的布局 <com.kuibu.jucai.widget.MyRadioGroup android:id=&quo ...

  3. jinja2批量生成python脚本

    ​ 在使用airflow的过程中需要大量的dag脚本进行性能测试,如果一个个去编写dag脚本未免太过麻烦,于是想到用python的jinja2模板引擎实现批量脚本生成. 先通过pip命令安装jinja ...

  4. HBase WAL原理学习

    1.概述 客户端往RegionServer端提交数据的时候,会写WAL日志,只有当WAL日志写成功以后,客户端才会被告诉提交数据成功,如果写WAL失败会告知客户端提交失败,换句话说这其实是一个数据落地 ...

  5. linux 操作系统级别监控 TOP命令

    Top命令是Linux下一个实时的.交互式的,对操作系统整体监控的命令,可以对CPU.内存.进程监控. 是Linux下最常用的监控命令. 第一行是任务队列信息 1 user 当前登录用户数load a ...

  6. python接口自动化测试七:获取登录的Cookies

    python接口自动化测试七:获取登录的Cookies,并关联到下一个请求   获取登录的cookies:loginCookies = r.cookies 把获取到的cookies传入请求:cooki ...

  7. Java8虚拟机(JVM)内存溢出实战

    前言 相信很多JAVA中高级的同学在面试的时候会经常碰到一个面试题 你是如何在工作中对JVM调优和排查定位问题的? 事实上,如果用户量不大的情况下,在你的代码还算正常的情况下,在工作中除非真正碰到与J ...

  8. log4j日志不输出的问题

    今天服务器上报错,想先去看一下日志进行排查,结果发现日志很久都没有输出过了.从上午排查到下午,刚刚解决,因此记录一下,但现在也只是知其然,并不知其所以然,所以如果大家有什么想法请在下方评论. 先说一下 ...

  9. Java方法调用的字节码指令学习

    Java1.8环境下,我们在编写程序时会进行各种方法调用,虚拟机在执行这些调用的时候会用到不同的字节码指令,共有如下五种: invokespecial:调用私有实例方法: invokestatic:调 ...

  10. Collections.unmodifiableMap,Collections.unmodifiableList,Collections.unmodifiableSet作用及源码解析

    在文章:Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析中mybatis的源码中用到了Collections.unmodifiableList方法,其实还有unmodifiabl ...