微服务容错限流Hystrix入门

为什么需要容错限流

  • 复杂分布式系统通常有很多依赖,如果一个应用不能对来自依赖 故障进行隔离,那么应用本身就处在被拖垮的风险中。在一个高流量的网站中,某个单一后端一旦发生延迟,将会在数秒内导致 所有应用资源被耗尽(一个臭鸡蛋影响一篮筐)。
  • 如秒杀、抢购、双十一等场景,在某一时间点会有爆发式的网络流量涌入,如果没有好的网络流量限制,任由流量压到后台服务实例,很有可能造成资源耗尽,服务无法响应,甚至严重的导致应用崩溃。

Hystrix是什么

Hystrix 能使你的系统在出现依赖服务失效的时候,通过隔离系统所依赖的服务,防止服务级联失败,同时提供失败回退机制,更优雅地应对失效,并使你的系统能更快地从异常中恢复。

Hystrix能做什么

  • 在通过第三方客户端访问(通常是通过网络)依赖服务出现高延迟或者失败时,为系统提供保护和控制
  • 在分布式系统中防止级联失败
  • 快速失败(Fail fast)同时能快速恢复
  • 提供失败回退(Fallback)和优雅的服务降级机制
  • 提供近似实时的监控、报警和运维控制手段

Hystrix设计原则

  • 防止单个依赖耗尽容器(例如 Tomcat)内所有用户线程
  • 降低系统负载,对无法及时处理的请求快速失败(fail fast)而不是排队
  • 提供失败回退,以在必要时让失效对用户透明化
  • 使用隔离机制(例如『舱壁』/『泳道』模式,熔断器模式等)降低依赖服务对整个系统的影响
  • 针对系统服务的度量、监控和报警,提供优化以满足近似实时性的要求
  • 在 Hystrix 绝大部分需要动态调整配置并快速部署到所有应用方面,提供优化以满足快速恢复的要求
  • 能保护应用不受依赖服务的整个执行过程中失败的影响,而不仅仅是网络请求

Hystrix设计思想来源

舱壁隔离模式

货船为了进行防止漏水和火灾的扩散,会将货仓分隔为多个,当发生灾害时,将所在货仓进行隔离就可以降低整艘船的风险。

断路器模式

熔断器就像家里的保险丝,当电流过载了就会跳闸,不过Hystrix的熔断机制相对复杂一些。

熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.

  • 当熔断器开关关闭时,请求被允许通过熔断器。如果当前健康状况高于设定阈值,开关继续保持关闭。如果当前健康状况低于设定阈值,开关则切换为打开状态。
  • 当熔断器开关打开时,请求被禁止通过。
  • 当熔断器开关处于打开状态,经过一段时间后,熔断器会自动进入半开状态,这时熔断器只允许一个请求通过。当该请求调用成功时,熔断器恢复到关闭状态。若该请求失败,熔断器继续保持打开状态, 接下来的请求被禁止通过。

Hystrix工作流程

官网原图

中文版

流程说明

  1. 每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
  2. 执行execute()/queue做同步或异步调用.
  3. 当前调用是否已被缓存,是则直接返回结果,否则进入步骤 4
  4. 判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤 8,进行降级策略,如果关闭进入步骤 5
  5. 判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤 6
  6. 调用HystrixCommand的run方法.运行依赖逻辑
  • 6.1. 调用是否出现异常,否:继续,是进入步骤8,
  • 6.2. 调用是否超时,否:返回调用结果,是进入步骤8
  1. 搜集5、6步骤所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态
  2. getFallback()降级逻辑.四种触发getFallback调用情况(图中步骤8的箭头来源):
    返回执行成功结果

两种资源隔离模式

线程池隔离模式

使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。

信号量隔离模式

使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)。

线程池隔离模式 VS 信号量隔离模式

Hystrix主要配置项


快速上手

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>1.5.12</version>
</dependency>
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-metrics-event-stream</artifactId>
    <version>1.5.12</version>
</dependency>
<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.12</version>
</dependency>

HystrixConfig

@Configuration
public class HystrixConfig {

    /**
     * 声明一个HystrixCommandAspect代理类,现拦截HystrixCommand的功能
     */
    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }

}

HelloService

@Service
public class HelloService {

    @HystrixCommand(fallbackMethod = "helloError",
            commandProperties = {
                    @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
                    @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")},
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "5"),
                    @HystrixProperty(name = "maximumSize", value = "5"),
                    @HystrixProperty(name = "maxQueueSize", value = "10")
            })
    public String sayHello(String name) {
        try {
            Thread.sleep( 15000 );
            return "Hello " + name + " !";
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String helloError(String name) {
        return "服务器繁忙,请稍后访问~";
    }

}

启动类

@SpringBootApplication
@RestController
public class HystrixSimpleApplication {

    @Autowired
    private HelloService helloService;

    public static void main(String[] args) {
        SpringApplication.run( HystrixSimpleApplication.class, args );
    }

    @GetMapping("/hi")
    public String hi(String name) {
        return helloService.sayHello( name );
    }

}

测试

访问 http://localhost:80809/hi?name=zhangsan

curl -X GET -d 'name=zhangsan' http://localhost:8080/hi

返回

服务器繁忙,请稍后访问~

源码

https://github.com/gf-huanchupk/SpringCloudLearning/tree/master/chapter16

参考

https://github.com/Netflix/Hystrix/wiki

https://blog.51cto.com/snowtiger/2057092

欢迎扫码或微信搜索公众号《程序员果果》关注我,关注有惊喜~

原文地址:https://www.cnblogs.com/huanchupkblog/p/10772274.html

时间: 2024-10-08 16:07:11

微服务容错限流Hystrix入门的相关文章

微服务熔断限流Hystrix之流聚合

简介 上一篇介绍了 Hystrix Dashboard 监控单体应用的例子,在生产环境中,监控的应用往往是一个集群,我们需要将每个实例的监控信息聚合起来分析,这就用到了 Turbine 工具.Turbine有一个重要的功能就是汇聚监控信息,并将汇聚到的监控信息提供给Hystrix Dashboard来集中展示和监控. 流程 实验 工程说明 工程名 端口 作用 eureka-server 8761 注册中心 service-hi 8762 服务提供者 service-consumer 8763 服

Spring Cloud构建微服务架构 服务容错保护(Hystrix断路器)【Dalston版】

前言 在前两篇<Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)>和<Spring Cloud构建微服务架构:服务容错保护(Hystrix依赖隔离)>中,我们对Hystrix提供的服务降级和依赖隔离有了基本的认识.下面我们将继续说说Hystrix的另外一个重要元件:断路器. 断路器 断路器模式源于Martin Fowler的Circuit Breaker一文."断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生

Spring Cloud 八:服务容错保护(Hystrix断路器)【Dalston版】

断路器 断路器模式源于Martin Fowler的Circuit Breaker一文."断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,"断路器"能够及时的切断故障电路,防止发生过载.发热.甚至起火等严重后果. 在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),直接切断原来的主逻辑调用.但是,在Hystrix中的断路器除了切断主逻辑的功能之外,还有更复

微服务SpringCloud项目架构搭建入门

Spring的微服务框架SpringCloud受到众多公司欢迎,给大家带来一篇框架搭建入门.本次采用的版本是Spring Cloud版本为Finchley.RELEASE. 一.SpringCloud项目简介 spring cloud: 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环境简单,可以在开发人员的电脑上跑. Spring Boot: 旨在简化创建产品级的 Spring 应用和服务,简化了配

7.Spring-Cloud服务容错保护之Hystrix初探

在微服务架构中,存在着多个服务单元,若一个单元出现故障,就很容易因依赖关系而出现故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统的架构更加不稳定,为了解决这样的问题,产生了断路器等一系列的服务保护机制. "断路器"本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路,"断路器"能够及时切断故障电路,防止发生过载.发热甚至起火等严重后果. 分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似于用电器发生短路)之后,通过断路器的故

六、服务容错保护(Hystrix服务降级)

1.简介 在微服务架构中,我们将系统拆分成立一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程间运行,依赖通过远程调用的方式执行,这样就可以因为网络原因或者依赖服务自身问题出现调用故障或延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务的积压,线程资源无法释放,最终导致自身服务的瘫痪,进一步甚至出现故障的蔓延导致整个系统的瘫痪.如果这样的架构存在如此严重的隐患,那么相较于传统的架构就会更加的不稳定.为了解决这样的问题,就产生

Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)

动手试一试 在开始使用Spring Cloud Hystrix实现断路器之前,我们先拿之前实现的一些内容作为基础,其中包括: eureka-server工程:服务注册中心,端口:1001 eureka-client工程:服务提供者,两个实例启动端口分别为2001 下面我们可以复制一下之前实现的一个服务消费者:eureka-consumer-ribbon,命名为eureka-consumer-ribbon-hystrix.下面我们开始对其进行改在: 第一步:pom.xml的dependencies

JAVA springboot微服务b2b2c电子商务系统-hystrix参数详解(八)

简介 上节我们讨论了hystrix+feign+ribbon,但是可能很多人都知道hystrix还有线程隔离,信号量隔离,等等各种参数配置,在这几就记录下hystrix的参数, 一.hystrix参数使用方法 通过注解@HystrixCommand的commandProperties去配置, 如下就是hystrix命令超时时间命令执行超时时间,为1000ms和执行是不启用超时 @RestController public class MovieController { @Autowired pr

Spring Cloud微服务Sentinel+Apollo限流、熔断实战

在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实项目实践过程,这中间被不少网络Demo示例级别水文误导过,为了以正视听特将实践过程加以总结,希望能够帮到有类似需要的朋友! 一.Sentinel概述 在基于Spring Cloud构建的微服务体系中,服务之间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素.在并发流量比较高