精华内容
下载资源
问答
  • @GetMapping(value = "/payment/hystrix/timeout/{id}",produces = MediaType.APPLICATION_JSON_VALUE) public String paymentInfo_Timeout(@PathVariable("id") Integer id){ String s = ...
  • 六、Hystrix服务降级与熔断 一、前言   当今环境下分布式已是当今系统架构的发展方向,但分布式同样面临着许多的问题。本文将从分布式系统面临的问题、解决方案、能解决哪些问题,并结合代码去演示.

    卑微程序员:各位客官,走过看过,不求三联,只需点赞


    SpringCloud系列目录:


    一、前言

      当今环境下分布式已是当今系统架构的发展方向,但分布式同样面临着许多的问题。本文将从分布式系统面临的问题、解决方案、能解决哪些问题,并结合代码去演示。文章中的代码都已提交到Github,如需自取。

    二、分布式系统面临的问题

    在这里插入图片描述
    服务雪崩:

    多个微服务之间调用的时候,假设微服务A调用B和微服务C,微服务B和微服务C又调用其他的服务,这就是所谓的扇出
    。如果扇出的连路上某个微服务的调用响应时间过长或者是不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统更崩溃,所谓的“雪崩效应”。
    对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的资源在几秒钟之内饱和。这些应用程序还会导致服务之间的延迟增加,备份队列,现成和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统

    解决方案(Hystrix)

    当依赖的服务发生故障时,对该服务做降级或者是熔断处理,降低对整个应用的影响
    官网地址:https://github.com/Netflix/Hystrix/wiki/How-To-Use
    目前Hystrix已不再更新,进入维护阶段。当然以后很多优秀的可用的方案,比如Sentinel。受限于篇幅,此文只涉及服务降级与熔断

    2.1 能干什么

    1)服务降级

    服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好的提示
    降级触发:程序运行异常、调用超时、服务熔断触发降级、线程池/信号量打满

    2)服务熔断

    达到设定的最大的服务访问,直接拒绝访问,然后调用服务降级方法并返回友好提示
    熔断过程:服务降级->熔断->恢复调用链路

    3)服务限流

    秒杀等高并发操作,设定并发量

    2.1 服务降级
    2.1.1 项目搭建与测试

    :项目可以单独建立,不适用Eureka,如果需要使用请参考之前的几篇文章,项目中所有的代码均已提交到github

    项目搭建,结构如下:
    在这里插入图片描述

    1)新建cloud-provider-hystrix-payment8001
    2)添加pom依赖

     <dependencies>
            <!--新增hystrix-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.atguigu.springcloud</groupId>
                <artifactId>cloud-api-commons</artifactId>
                <version>${project.version}</version>
            </dependency>
            
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    

    3)修改yml

    server:
      port: 8001
    
    eureka:
      client:
        register-with-eureka: true    #表识不向注册中心注册自己
        fetch-registry: true   #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
        service-url:
          #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址(此处我有修改hosts配置文件)
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
    
    spring:
      application:
        name: cloud-provider-hystrix-payment
     
    

    4)主启动类

    @SpringBootApplication
    @EnableEurekaClient
    public class PaymentHystrixMain8001 {
        public static void main(String[] args) {
            SpringApplication.run(PaymentHystrixMain8001.class,args);
        }
    }
    

    5)业务代码

    @Service
    public class PaymentService {
    
        //成功
        public String paymentInfo_OK(Integer id){
            return "线程池:"+Thread.currentThread().getName()+"   paymentInfo_OK,id:  "+id+"\t"+"哈哈哈"  ;
        }
    
        //失败
        public String paymentInfo_TimeOut(Integer id){
            int timeNumber = 3;
            try { TimeUnit.SECONDS.sleep(timeNumber); }catch (Exception e) {e.printStackTrace();}
            return "线程池:"+Thread.currentThread().getName()+"   paymentInfo_TimeOut,id:  "+id+"\t"+"呜呜呜"+" 耗时(秒)"+timeNumber;
        }
    
    }
    
    
    @RestController
    @Slf4j
    public class PaymentController {
    
        @Resource
        private PaymentService paymentService;
    
        @Value("${server.port}")
        private String serverPort;
    
        @GetMapping("/payment/hystrix/ok/{id}")
        public String paymentInfo_OK(@PathVariable("id") Integer id){
            String result = paymentService.paymentInfo_OK(id);
            log.info("*******result:"+result);
            return result;
        }
        @GetMapping("/payment/hystrix/timeout/{id}")
        public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
            String result = paymentService.paymentInfo_TimeOut(id);
            log.info("*******result:"+result);
            return result;
        }
    }
    

    测试两个接口
    先启动两个Eureka服务,然后再启动8001服务,这里我们分别测试两个接口。

    在这里插入图片描述
    在这里插入图片描述
    代码很简单,服务也是可以跑通的。如果在高并发的情况下上述的服务又会如何呢?接下来我们使用Jmater来简单的压测一下,当然在实际的项目中仅仅使用Jmater是远远不够的,此处仅供测试使用

    使用压测timeout接口

    1)新建一个线程组
    在这里插入图片描述
    2)在线程组下新建一个http请求
    在这里插入图片描述
    3)设置协议、服务器名称、端口号、路径
    在这里插入图片描述
    4)ctrl+s保存之后执行
    在这里插入图片描述

    5)访问没有休眠的方法发现该方法有了延时
    http://localhost:8001/payment/get/info/ok/3
    在这里插入图片描述

    以上是对服务提供者进行压测,如果有客户端调用8001服务,那结果同样是等待

    故障现象和原因

    8001同一层次的其他接口服务迪被调用过多,导致tomcat线程中的线程全部被占用,如果再调用8001服务中的其他接口,就需要等待线程被释放。

    2.1.2 解决方式
    • 超时导致服务器变慢:超时不再等待
    • 出错(宕机或程序运行出错)出错有兜底

    通过设置自身调用超时时间峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作为降级的fallback

    1)业务类启用@HystrixCommand

    一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。当方法paymentInfo_Timeout()执行时间超过设定好的之间自动执行降级方法paymentInfo_TimeOutHandler(),当然此处也可以写自己的降级逻辑

    @Service
    public class PaymentServiceImpl implements IPaymentService {
    
        @Override
        public String paymentInfo_Ok(Integer id) {
            return "线程池" + Thread.currentThread().getName() + " paymentInfo_Ok id" + id;
        }
    
        @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
                @HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds", value = "3000")
        })
        public String paymentInfo_Timeout(Integer id) {
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "线程池" + Thread.currentThread().getName() + " id" + id;
        }
    
        public String paymentInfo_TimeOutHandler(Integer id) {
            return "线程池" + Thread.currentThread().getName() + " paymentInfo_TimeOutHandler方法超时" + id;
        }
    

    2)主启动类激活

    添加新注解@EnableCircuitBreaker

    @SpringBootApplication
    @EnableEurekaClient
    @EnableCircuitBreaker
    public class PaymentHystrixMain8005 {
        public static void main(String[] args) {
            SpringApplication.run(PaymentHystrixMain8005.class,args);
        }
    }
    
    

    注:服务端与客户端的降级使用注解以及配置略有差别,当然原理是相同的

    3)降级测试

    接下来我们直接调用timeout方法来进行测试

    2.2 服务熔断

    展开全文
  • SpringCloud Hystrix服务降级与熔断 Hystrix是什么? 在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离...

    Hystrix是什么?

    在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。

    Hystrix解决了什么问题

    复杂分布式体系结构中的应用程序有许多依赖项,每个依赖项在某些时候都不可避免地会失败。如果主机应用程序没有与这些外部故障隔离,那么它有可能被他们拖垮。
    例如,对于一个依赖于30个服务的应用程序,每个服务都有99.99%的正常运行时间,你可以期望如下: 99.9930 = 99.7% 可用
    也就是说一亿个请求的0.03% = 3000000 会失败
    如果一切正常,那么每个月有2个小时服务是不可用的
    现实通常是更糟糕

    服务降级

    什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

    1. pom
    <!--hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <!--eureka client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--openfeign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    1. yaml
    server:
      port: 80
    
    spring:
      application:
        name: cloud-hystrix-consumer
    #将服务注册到eureka
    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:7001/eureka/
    feign:
      hystrix:
        enabled: true
    
    1. 主启动类加@EnableHystrix注解
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    @EnableHystrix
    public class HystrixConsumerMain {
        public static void main(String[] args) {
            SpringApplication.run(HystrixConsumerMain.class,args);
        }
    }
    
    1. ConsumerService接口(Feign接口+注解实现服务接口调用)
    @Component
    @FeignClient(value = "CLOUD-HYSTRIX-PROVIDER") //调用服务提供方8001
    public interface ConsumerService {
    	//请求会立即返回结果
        @GetMapping(value = "/hystrix/provider/ok")
        public String  provider_OK();
        //请求会延迟3秒返回结果
        @GetMapping(value = "/hystrix/provider/timeout")
        public String  provider_TimeOut();
    }
    

    8001服务提供方ProviderService.java相应代码

    /**
    * 正常
    * @return
    */
    public String provider_OK() {
       return "线程池:" + Thread.currentThread().getName() + " provider_OK" + "\t" ;
    }
    /**
     * 超时
     * @return
     */
    public String provider_TimeOut() {
        try {
            TimeUnit.MILLISECONDS.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + " 3秒provider_TimeOut"  + "\t" ;
    }
    
    1. ConsumerController
    @RestController
    @Slf4j
    public class ConsumerController {
        @Resource
        private ConsumerService consumerService;
    
        @GetMapping(value = "/hystrix/consumer/ok")
        public String  consumer_OK(){
            return consumerService.provider_OK();
        }
    
        @GetMapping(value = "/hystrix/consumer/timeout")
        public String  consumer_TimeOut(){
            try {
            }catch (Exception e){
                e.printStackTrace();
            };
            return consumerService.provider_TimeOut();
        }
    }
    
    1. 使用Jmeter进行压力测试
      来20000个并发压死8001服务提供方,20000个请求都去访问provider_TimeOut服务
      在这里插入图片描述
      在这里插入图片描述
      浏览器访问provider_OK服务也会出现延迟响应,正常情况不会出现延迟(http://localhost:8001/hystrix/provider/ok)
      浏览器访问consumer_OK偶尔会出现超时报错(http://localhost/hystrix/consumer/ok)

    OpenFeign默认等待一秒钟,超时就会报错

    1. 服务降级
    • 第一种:一个方法一个fallbackMethod处理
    @GetMapping(value = "/hystrix/consumer/timeout")
    @HystrixCommand(fallbackMethod = "consumerTimeOutFallbackMethod",
    commandProperties = {@HystrixProperty(name= HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS,value = "2000")})//两秒超时
    public String  consumer_TimeOut() {
        return consumerService.provider_TimeOut();
    }
    
    public String consumerTimeOutFallbackMethod() {
        return "80端口请求:请求超时或者自己运行出错!";
    }
    
    • 第二种:一个类一个统一fallbackMethod处理
    @RestController
    @Slf4j
    @DefaultProperties(defaultFallback = "commonFallbackMethod")
    public class ConsumerController {
        @Resource
        private ConsumerService consumerService;
    
        @HystrixCommand
        @GetMapping(value = "/hystrix/consumer/ok")
        public String  consumer_OK(){
            return consumerService.provider_OK();
        }
    
        @GetMapping(value = "/hystrix/consumer/timeout")
        @HystrixCommand
        public String  consumer_TimeOut() {
            return consumerService.provider_TimeOut();
        }
        
        public String commonFallbackMethod() {
            return "80端口请求:请求超时或者自己运行出错!公共处理";
        }
    
    • 第三种:Feign客户端定义的接口添加一个服务降级处理的实现类(可实现业务解耦)
      新建ConsumerFallBackService.java
    @Component
    public class ConsumerFallBackService implements ConsumerService{
        @Override
        public String provider_OK() {
    
            return "ConsumerFallBackService-80端口:provider_OK超时或异常";
        }
    
        @Override
        public String provider_TimeOut() {
            return "ConsumerFallBackService-80端口:provider_TimeOut超时或异常";
        }
    }
    

    ConsumerService.java@FeignClient注解增加fallback

    @Component
    @FeignClient(value = "CLOUD-HYSTRIX-PROVIDER",fallback = ConsumerFallBackService.class)
    public interface ConsumerService {
    
        @GetMapping(value = "/hystrix/provider/ok")
        public String  provider_OK();
    
        @GetMapping(value = "/hystrix/provider/timeout")
        public String  provider_TimeOut();
    }
    

    服务熔断

    服务雪崩

    多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C有调用其他的微服务,这就是所谓的”扇出”,如扇出的链路上某个微服务的调用响应式过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统雪崩,所谓的”雪崩效应”。

    服务熔断: 熔断机制是应对雪崩效应的一种微服务链路保护机制,

    当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回”错误”的响应信息。当检测到该节点微服务响应正常后恢复调用链路,在SpringCloud框架机制通过Hystrix实现,Hystrix会监控微服务见调用的状况,当失败的调用到一个阈值,缺省是5秒内20次调用失败就会启动熔断机制,熔断机制的注解是@HystrixCommand

    对于熔断机制的实现,Hystrix设计了三种状态:

    1.熔断关闭状态(Closed) 服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。
    2.熔断开启状态(Open) 在固定时间窗口内(Hystrix默认是10秒),接口调用出错比率达到一个阈值(Hystrix默认为50%),会进入熔断开启状态。进入熔断状态后,后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法。
    3.半熔断状态(Half-Open)

    在进入熔断开启状态一段时间之后(Hystrix默认是5秒),熔断器会进入半熔断状态。所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断关闭状态。

    代码实现

    @HystrixCommand(fallbackMethod = "provider_CircuitBreakerFallBack",
    commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED,value = "true"),
    @HystrixProperty(name= HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "10"),         //熔断触发的最小个数
    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,value = "10000"), //熔断多少秒后去尝试请求
    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,value = "50")       //失败率达到多少百分比后熔断
    }
    )
    public String provider_CircuitBreaker(Integer id) {
        if (id < 0){
            throw new RuntimeException("服务熔断");
        }
        return "线程池:" + Thread.currentThread().getName() + "---provider_CircuitBreaker---"  + "正常返回" ;
    }
    public String provider_CircuitBreakerFallBack(Integer id){
        return "线程池:" + Thread.currentThread().getName() + "---provider_CircuitBreakerFallBack---"  + "服务熔断" ;
    }
    

    测试
    id>=0:输出provider_CircuitBreaker方法的返回值
    id < 0:输出provider_CircuitBreakerFallBack方法的返回值(fallback方法)

    当请求时大于10,并且失败率达到50%,服务熔断开启,输入正值也走fallback方法
    服务熔断

    十秒之后,进入半熔断状态,如果服务能正常调用,则服务恢复(熔断关闭状态);否则重新进入熔断关闭状态

    展开全文
  • Hystrix降级与熔断测试构建服务Eureka Server注册中心服务生产者服务消费者Hystrix监控服务测试测试方案预期目标开始测试 构建服务 为了测试Hystrix降级与熔断功能,此处构建了Eureka Server注册中心服务、...

    构建服务

    为了测试Hystrix的降级与熔断功能,此处构建了Eureka Server注册中心服务、Eureka Client的生产者和消费者两个服务、Hystrix Dashboard服务监控平台,总共四个服务。

    Eureka Server注册中心

    这里可以参考我之前写的一篇文章:https://blog.csdn.net/m0_43420705/article/details/111763158
    通过这篇教程即可构建出Eureka Server注册中心。

    服务生产者

    新建一个springboot项目为其添加控制层向外提供一个接口:

    @RestController
    @RequestMapping("/")
    public class ProducerController {
        @GetMapping("/getinfo")
        public String getInfo() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "方法正常执行";
        }
    }
    

    当访问此接口时会延迟5秒钟返回结果,以此来测试消费者端服务调用的超时然后降级或熔断的情况。

    服务消费者

    新建一个springboot项目为其添加控制层向外提供接口:

    @RestController
    @RequestMapping("/")
    public class ConsumerController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/get1")
        @HystrixCommand(
                //线程池标识
                threadPoolKey = "test1ThreadPool",
    
                //线程池属性配置
                threadPoolProperties = {
                        //线程核心数
                        @HystrixProperty(name = "coreSize", value = "3"),
                        //线程池队列大小
                        @HystrixProperty(name = "maxQueueSize", value = "100")
                },
    
                //设置test1方法对应的降级方法:testFallback1
                fallbackMethod = "testFallback1",
    
                commandProperties = {
                        //设置超时时间为1秒则改为调用降级方法
                        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
                        //失败时开启一个固定时间的的窗口 此处设置为10秒
                        @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"),
                        //熔断跳闸所需的最小请求数 此处设置为4次
                        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "4"),
                        //失败次数所占请求的百分比 此处设置为50% 超过50%则熔断跳闸
                        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                        //跳闸后会产生另一个活动窗口,每隔一段时间让一个请求去测试被跳闸的服务,若无问题则重置断路器,有问题则一直按固定时间间隔重复用一个请求去测试 此处时间间隔设置为5秒
                        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000")
                }
        )
        public String test1() {
            return restTemplate.getForObject("http://eureka-client-producer/getinfo", String.class);
        }
    
        public String testFallback1() {
            return "降级方案1";
        }
    }
    

    这里添加了一个test1()接口和其对应的testFallback1()降级方法,通过在接口方法上添加@HystrixCommand注解表明该方法可进行熔断和服务降级,注解中的参数可实现细节的配置,具体所用到的每个参数所对应的功能都在上面代码注释中写出了。

    Hystrix监控服务

    再新建一个springboot项目,其pom.xml文件中所需依赖如下:

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    

    在application.yml配置文件中添加如下配置:

    spring:
      application:
        name: hystrix-dashboard-server
    server:
      port: 8204
    eureka:
      client:
        service-url.defaultZone: http://alee:123456@{Eureka注册中心IP}:{端口}/eureka/
        register-with-eureka: true
        fetch-registry: true
      instance:
        prefer-ip-address: true
        instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    hystrix:
      dashboard:
        proxy-stream-allow-list: "localhost"
    

    最后在启动类上加上@EnableHystrixDashboard注解以使用Hystrix监控仪表盘。

    测试

    测试方案

    这里使用Postman测试工具进行测试,然后通过观察Hystrix Dashboard仪表盘的变化判断测试是否成功。

    预期目标

    通过观察消费者服务的test1()接口的HystrixCommand配置可知,每次发送请求去调用该接口程序一定会超时,所以当最开始服务未熔断时在10秒钟之内发送4个请求后服务就会熔断,然后在每个5秒钟内连续发多个请求的话,第一个请求会显示超时,剩下的请求会显示短路。

    开始测试

    在Postman中新建一个请求:
    在这里插入图片描述
    在Collection Runner中选择该请求并发4次:
    在这里插入图片描述
    点击Run测试接口按钮可以看到执行第三个请求后服务并未熔断,在第四个请求完之后服务被熔断:
    在这里插入图片描述
    在这里插入图片描述
    现在服务已熔断的情况下再次发送10个请求测试:
    在这里插入图片描述
    可以看到第一个请求结果是超时,后面9个是短路,因为熔断之后每隔5秒钟的第一个请求依然会去调用test1()接口,而这5秒钟里剩余的请求不会去调用test1()接口,而是直接调用降级方法,并且请求结果会显示短路。
    测试完成。

    展开全文
  • Hystrix服务降级熔断

    2021-05-20 18:21:26
    Hystrix服务降级 首先在启动类开启Hystrix,在启动类上加@EnableHystrix注解 使用@HystrixCommand注解进行降级 服务降级 @FeignClient(value = "dm-admin-service", fallbackFactory = ...

    Hystrix服务降级

    首先在启动类开启Hystrix,在启动类上加@EnableHystrix注解

    使用@HystrixCommand注解进行降级

    服务降级

    @FeignClient(value = "dm-admin-service", fallbackFactory = AdminFeignServiceFallbackFactory.class)
    public interface AdminFeignService 
    {
        @RequestMapping(value = "/account/info", method = RequestMethod.POST)
        Object getAccountInfo(@RequestBody SessionPARM sessionPARM);
    }
    
    @Component
    @Slf4j
    public class AdminFeignServiceFallbackFactory implements FallbackFactory<AdminFeignService> 
    {
        @Override
        public AdminFeignService create(Throwable arg0) {
            return new AdminFeignService() {
                @Override
                public Object getAccountInfo(SessionPARM sessionPARM) {
                    throw new RuntimeException(arg0);
                }
     }
    
    

    在YAML中开启Hystrix

    feign:
      hystrix:
        enabled: true #在feign中开启hystrix
    

    服务熔断

    在方法上直接加@HystrixCommand

    public class PaymentController
    {
    	@Autowired
    	private PaymentService paymentService;
    	
    	@GetMapping("/consumer/payment/{id}")
    	@HystrixCommand(fallbackMethod="payment_Global_FallbackMethod",commandProperties={
    @HystrixProperty(name="circuitBreaker.enable",value="true"),//是否开启断路器
    @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="20"),//请求次数
    @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),//时间窗口期
    @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="60"),//失败率达到多少后跳闸60%
    })
    	public String paymentInfo(@PathVariable("id) Integer id)
    	{
    		return paymentService.paymentInfo(id);
    	}
    	
    	@GetMapper("consumer/paymentTimeOut/{id}")
    	@HystrixCommand
    	public String paymentTimeOut(@PathVariable("id) Integer id)
    	{
    		return paymentService.paymentTimeOut(id);
    	}
    	public String payment_Global_FallbackMethod()
    	{
    		return "全局降级"
    	}
    }
    

    熔断器总结:

    一、断路器在什么情况下开始起作用:
    涉及到断路器的三个重要参数:快照时间窗、请求总数阀值、错误百分比阀值。
    1、快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒

    2、请求总数阀值:在快照时间窗内,必须满足请求总数阀值才有资格熔断。默认为20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。

    3、错误百分比阀值:当请求总数在快照时间内超过了阀值,比如发生了30次调用,如果在这个30此调用中,有15次发生了超时异常,也就是超过了50%的错误百分比,在默认设定50%阀值情况下,这时候就会将断路器打开。

    二、熔断器开启或关闭的条件:
    1、当满足一定的阀值的时候(默认10秒内超过20个请求次数)
    2、当失败率达到一定的时候(默认10秒内超过50%的请求失败)
    3、到达以上阀值,断路器将会开启
    4、当断路器开启的时候,所有请求都不会进行转发
    5、一段时间之后(默认5秒),这个时候断路器是半开状态,会让其中一个请求进行转发,如果成功,断路器会关闭,若失败,继续开启。重复4和5

    三、断路器打开之后

    1、再有请求调用的时候,将会调用主逻辑,而是直接调用降级fallback。通过断路器,实现了自动的发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。

    2、原来的主逻辑要如何恢复呢?
    对于这一问题,hystrix也为我们实现了自动修复功能。
    当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的成为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。

    展开全文
  • import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @author Xkuna * @date 2020/8/9 19:45. */ @SpringBootApplication...
  • 一、原理: 一个单体服务,拆成多个微服务A、B、C,一切正常的时候还好,万一A有个功能需要调用B的方法, ...那就用Hystrix服务降级熔断吧。 这东西听起来好像有点高级,其实说白了, 熔断就是请求一个服...
  • 1.熔断机制概述:熔断机制是应对雪崩效应的一种微服务链路保护机制,当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回错误的响应信息,当检测到该节点...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,330
精华内容 6,532
关键字:

hystrix服务降级与熔断