zoukankan      html  css  js  c++  java
  • SpringCloud Hystrix使用和配置,SpringCloud Hystrix服务熔断降级

    SpringCloud Hystrix使用和配置,SpringCloud Hystrix服务熔断降级

    ================================

    ©Copyright 蕃薯耀 2021-03-15

    https://www.cnblogs.com/fanshuyao/

    一、SpringCloud Hystrix概述
    Hystrix不再处于积极开发中,并且目前处于维护模式.Hystrix(版本1.5.18)足够稳定,可以满足Netflix现有应用程序的需求。

    Hystrix是一个延迟和容错库,旨在隔离对远程系统,服务和第三方库的访问点,停止级联故障,并在不可避免发生故障的复杂分布式系统中实现弹性。

    在分布式环境中,不可避免地会有许多服务依赖项中的某些失败。 Hystrix是一个库,可通过添加等待时间容限和容错逻辑来帮助您控制这些分布式服务之间的交互。 Hystrix通过隔离服务之间的访问点,停止服务之间的级联故障并提供后备选项来实现此目的,所有这些都可以提高系统的整体弹性。

    Hystrix旨在执行以下操作:
    1、提供保护并控制延迟和失败,以及通过第三方客户端库(通常是通过网络)访问的依赖项的失败。
    2、停止复杂的分布式系统中的级联故障。
    3、快速失败,迅速恢复。
    4、回退并在可能的情况下正常降级。
    5、启用近乎实时的监视,警报和操作控制。

    架构流程图:

    circuit-breaker:

    二、SpringCloud Hystrix使用和配置,以及服务熔断降级
    服务提供者:springCloud-hystrix-provider-8651
    服务消费者:springCloud-hystrix-web-8655
    一般在服务消费者实现服务熔断降级,当然服务提供者也同样可以实现。
    下面以服务消费者实现服务熔断降级为例进行配置开发。

    1、pom.xml引入依赖
    引入openfeign、eureka-client、hystrix

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.2.7.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        <version>2.2.7.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        <version>2.2.7.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.4.4</version>
    </dependency>

    2、application.properties配置文件修改
    启动hystrix:将feign.hystrix.enabled设置为true

    server.port=8655
    
    spring.application.name=SPRINGCLOUD-EUREKA-FEIGN-HYSTRIX
    
    #eureka服务端的实例名称
    eureka.instance.hostname=HOSTNAME-EUREKA-FEIGN-HYSTRIX-8655
    
    #eureka实例名称
    eureka.instance.instance-id=INSTANCEID-EUREKA-FEIGN-HYSTRIX-8655
    #路径显示IP地址
    eureka.instance.prefer-ip-address=true
    #eureka客户端向服务端发送心跳的时间间隔,单元为秒,默认为30秒
    eureka.instance.lease-renewal-interval-in-seconds=2
    #eureka服务端收到最后一次心跳等待的时间上限,超时将移除服务,单元为秒,默认为90秒
    eureka.instance.lease-expiration-duration-in-seconds=5
    
    #false表示向注册中心注册自己
    eureka.client.register-with-eureka=false
    #是否从Eureka抓取已有的注册信息,默认为true。单节点不用设置,集群必须设置为true,才能配置ribbon使用负载均衡
    eureka.client.fetch-registry=true
    #设置与Eureka server交互的地址查询服务和注册服务都需要依赖这个地址
    eureka.client.service-url.defaultZone=http://eureka8501.com:8501/eureka
    
    
    #feign客户端建立连接最大的时间
    feign.client.config.default.read-timeout=3000
    #建立连接后,从服务器获取响应结果的最大时间
    feign.client.config.default.connect-timeout=3000
    
    #打印日志的4个级别:none、basic、headers、full
    feign.client.config.default.logger-level=full
    #设置要日志打印的接口类
    logging.level.com.lqy.springCloud.hystrix.web.service.HystrixService: DEBUG
    
    #启动hystrix
    feign.hystrix.enabled=true

    3、启动类
    有三个注解:
    EnableFeignClients:启动FeignClients
    EnableEurekaClient:启动EurekaClient
    EnableHystrix:启动Hystrix

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableFeignClients
    @EnableEurekaClient
    @EnableHystrix
    public class SpringCloudHystrixWeb8655Application {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudHystrixWeb8655Application.class, args);
        }
    
    }

    4、FeignClient接口定义及降级实现
    使用@FeignClient注解定义,value:远程服务名,fallback:服务降级的实现类

    接口调用定义类:

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.lqy.springCloud.hystrix.web.controller.Result;
    import com.lqy.springCloud.hystrix.web.service.impl.HystrixServiceImpl;
    
    /**
     *   使用OpenFeign调用远程服务实现服务降级
     * value:远程服务名
     * fallback:服务降级的实现类
     * 
     *
     */
    @FeignClient(value="SPRINGCLOUD-EUREKA-SERVER-HYSTRIX", fallback = HystrixServiceImpl.class)
    public interface HystrixService {
    
        @RequestMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
        public Result test();
        
        
        @RequestMapping(value = "/get/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
        public Result get(@PathVariable(required = false, value = "text") String text);
        
        
        @RequestMapping(value = "/cal/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
        public Result cal(@PathVariable(value = "text") int text) throws InterruptedException;
        
        
        @RequestMapping(value = "/timeout/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
        public Result timeout(@PathVariable(required = false, value = "text") String text) throws InterruptedException;
        
    }

    降级实现类:
    这里需要注意的是:必须要加上注解@Component

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import com.lqy.springCloud.hystrix.web.controller.Result;
    import com.lqy.springCloud.hystrix.web.service.HystrixService;
    
    /**
     * 必须要有注解:@Component,不然会报错
     *
     */
    @Component
    public class HystrixServiceImpl implements HystrixService{
    
        @Value("${server.port}")
        private String serverPort;
        
        @Override
        public Result test() {
            return Result.fail(serverPort);
        }
    
        @Override
        public Result get(String text) {
            return Result.fail(serverPort);
        }
    
        @Override
        public Result cal(int text) throws InterruptedException {
            return Result.fail(serverPort);
        }
    
        @Override
        public Result timeout(String text) throws InterruptedException {
            return Result.fail(serverPort);
        }
        
    }

    缺少@Component,启动报错:

    Caused by: java.lang.IllegalStateException: No fallback instance of type class com.lqy.springCloud.hystrix.web.service.impl.HystrixServiceImpl found for feign client SPRINGCLOUD-EUREKA-SERVER-HYSTRIX
        at org.springframework.cloud.openfeign.HystrixTargeter.getFromContext(HystrixTargeter.java:81) ~[spring-cloud-openfeign-core-2.2.7.RELEASE.jar:2.2.7.RELEASE]
        at org.springframework.cloud.openfeign.HystrixTargeter.targetWithFallback(HystrixTargeter.java:72) ~[spring-cloud-openfeign-core-2.2.7.RELEASE.jar:2.2.7.RELEASE]
        at org.springframework.cloud.openfeign.HystrixTargeter.target(HystrixTargeter.java:49) ~[spring-cloud-openfeign-core-2.2.7.RELEASE.jar:2.2.7.RELEASE]

    5、、不使用FeignClient接口,自己实现服务降级

    使用注解@HystrixCommand进行服务降级,通过fallbackMethod方法实现当服务降级时回调的方法;
    commandProperties可以不配置,示例中配置了超时(3秒超时,调用服务降级)。
    HystrixProperty的配置可以见:

    https://github.com/Netflix/Hystrix/wiki/Configuration
    import java.util.concurrent.TimeUnit;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import com.lqy.springCloud.hystrix.web.controller.Result;
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
    
    /**
     *   自带服务实现,不使用OpenFeign,使用@HystrixCommand
     * @HystrixCommand:注解实现服务降级
     * 
     *
     */
    @Service
    public class HystrixCommandServiceImpl {
    
        @Value("${server.port}")
        private String serverPort;
        
        @HystrixCommand(fallbackMethod = "selfTimeoutFallBack", commandProperties = {
                @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "3000")
        })
        public Result selfTimeout() throws InterruptedException {
            TimeUnit.SECONDS.sleep(5);
            return Result.ok(serverPort);
        }
        
        public Result selfTimeoutFallBack() throws InterruptedException {
            return Result.failMsg(serverPort + ":服务器请求超时,请重试");
        }
        
    }

    6、Controller调用
    hystrixService是使用OpenFeign调用远程服务
    hystrixCommandServiceImpl是调用自己本身的服务

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.lqy.springCloud.hystrix.web.service.HystrixService;
    import com.lqy.springCloud.hystrix.web.service.impl.HystrixCommandServiceImpl;
    
    
    @RestController
    public class WebController {
    
        @Value("${server.port}")
        private String serverPort;
        
        @Autowired
        private HystrixService hystrixService;
        @Autowired
        private HystrixCommandServiceImpl hystrixCommandServiceImpl;
        
        @RequestMapping("/self")
        public Result self() {
            return Result.ok("端口:" + serverPort);
        }
        
        @RequestMapping("/test")
        public Result test() {
            return hystrixService.test();
        }
        
        @RequestMapping(value = "/get/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
        public Result get(@PathVariable(required = false, value = "text") String text) throws InterruptedException {
            return hystrixService.get(text);
        }
        
        @RequestMapping(value = "/cal/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
        public Result cal(@PathVariable(value = "text") int text) throws InterruptedException {
            return hystrixService.cal(text);
        }
        
        @RequestMapping("/timeout/{text}")
        public Result timeout(@PathVariable(required = false, value = "text") String text) throws InterruptedException {
            return hystrixService.timeout(text);
        }
        
        
        @RequestMapping("/selfTimeout")
        public Result selfTimeout() throws InterruptedException {
            return hystrixCommandServiceImpl.selfTimeout();
        }
        
        
    }

    7、Hystrix服务降级测试


    调用远程服务获取数据:

    http://127.0.0.1:8655/get/ccbb

    {
      "result": true,
      "timestamp": "2021-03-15 11:31:05",
      "msg": "操作成功。",
      "datas": "端口:8651,ccbb"
    }


    调用远程服务超时:
    http://127.0.0.1:8655/timeout/ccbb

    {
    "result": false,
    "timestamp": "2021-03-15 11:31:29",
    "msg": "操作失败!",
    "datas": "8655"
    }

    调用远程服务发生错误(除0):

    http://127.0.0.1:8655/cal/0
    {
    "result": false,
    "timestamp": "2021-03-15 11:32:45",
    "msg": "操作失败!",
    "datas": "8655"
    }

    调用本身服务降级:
    http://127.0.0.1:8655/selfTimeout

    {
    "result": false,
    "timestamp": "2021-03-15 11:32:10",
    "msg": "8655:服务器请求超时,请重试",
    "datas": null
    }

    8、@HystrixCommand 默认是1秒超时,超时报错:

    @HystrixCommand
    public Result timeout(String text) throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        return Result.ok(text);
    }
    
    There was an unexpected error (type=Internal Server Error, status=500).
    timeout timed-out and fallback failed.
    com.netflix.hystrix.exception.HystrixRuntimeException: timeout timed-out and fallback failed.
        at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:832)
        at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:807)
    Caused by: java.util.concurrent.TimeoutException
        at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:997)
        at com.netflix.hystrix.AbstractCommand.access$500(AbstractCommand.java:60)
        at com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:609)
        at com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:601)
        at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)

    三、@HystrixCommand属性配置
    官网地址:

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

    1、Command Properties(命令属性)(Command 注解相关的属性配置)

    Execution属性

    execution.isolation.strategy
    execution.isolation.thread.timeoutInMilliseconds
    execution.timeout.enabled
    execution.isolation.thread.interruptOnTimeout
    execution.isolation.thread.interruptOnCancel
    execution.isolation.semaphore.maxConcurrentRequests

     

    Fallback属性

    fallback.isolation.semaphore.maxConcurrentRequests
    fallback.enabled

    Circuit Breaker属性

    circuitBreaker.enabled
    circuitBreaker.requestVolumeThreshold
    circuitBreaker.sleepWindowInMilliseconds
    circuitBreaker.errorThresholdPercentage
    circuitBreaker.forceOpen
    circuitBreaker.forceClosed

    circuitBreaker.enabled

    Default Value:true

    此属性确定断路器是否将用于跟踪运行状况以及在跳闸时用于短路请求。

     

    circuitBreaker.requestVolumeThreshold

    Default Value :20

    此属性在滚动窗口中设置将使电路跳闸的最小请求数。

    例如,如果值为20,则如果在滚动窗口(例如10秒的窗口)中仅收到19个请求,则即使所有19个失败,电路也不会跳闸断开。

    circuitBreaker.sleepWindowInMilliseconds

    Default Value :5000

    此属性设置在电路跳闸后拒绝请求的时间,然后允许再次尝试确定是否应再次闭合电路。

     

    circuitBreaker.errorThresholdPercentage

    Default Value:50

    该属性设置错误百分比,电路应在该百分比或以上跳闸,并启动对后备逻辑的短路请求。

    Metrics属性

    metrics.rollingStats.timeInMilliseconds
    metrics.rollingStats.numBuckets
    metrics.rollingPercentile.enabled
    metrics.rollingPercentile.timeInMilliseconds
    metrics.rollingPercentile.numBuckets
    metrics.rollingPercentile.bucketSize
    metrics.healthSnapshot.intervalInMilliseconds

    Request Context属性

    requestCache.enabled
    requestLog.enabled

    2、Collapser Properties(折叠器属性

    maxRequestsInBatch
    timerDelayInMilliseconds
    requestCache.enabled

    3、Thread Pool Properties(线程池属性

    coreSize
    maximumSize
    maxQueueSize
    queueSizeRejectionThreshold
    keepAliveTimeMinutes
    allowMaximumSizeToDivergeFromCoreSize
    metrics.rollingStats.timeInMilliseconds
    metrics.rollingStats.numBuckets

    四、SpringCloud Hystrix dashboard2.2.7使用和配置,SpringCloud Hystrix dashboard服务监控

    https://www.cnblogs.com/fanshuyao/p/14539320.html

    (时间宝贵,分享不易,捐赠回馈,^_^)

    ================================

    ©Copyright 蕃薯耀 2021-03-15

    https://www.cnblogs.com/fanshuyao/

    今天越懒,明天要做的事越多。
  • 相关阅读:
    1.01与37.8
    CakePHP 2.x CookBook 中文版 第七章 模型 之 检索数据
    CakePHP 2.x CookBook 中文版 第七章 模型
    CakePHP 2.x CookBook 中文版 第七章 模型 之 数据校验
    CakePHP 2.x CookBook 中文版 第五章 控制器 之 请求和响应对象
    CakePHP 2.x CookBook 中文版 第五章 控制器 之 脚手架
    CakePHP 2.x CookBook 中文版 第七章 模型 之 保存数据
    CakePHP 2.x CookBook 中文版 第三章 入门 之 CakePHP 的结构
    Zend Studio 10 phpFormatter 错误的解决
    CakePHP 2.x CookBook 中文版 第三章 入门 之 CakePHP 的文件夹结构
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/14537475.html
Copyright © 2011-2022 走看看