欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hystrix实现限流和熔断

程序员文章站 2022-07-15 13:02:56
...

Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
将服务的接口使用hystrix线程池做隔离,可以实现限流和熔断的效果。配合天舟平台提供的SpringCloudConfig配置中心,可以在不重启服务的情况下,动态调整hystrix限流的参数。

springboot工程使用hystrix的配置步骤:
1.pom.xml:

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>

2.开启hystrix及hystrixDashboard:

入口类加注解,@EnableHystrix,@EnableHystrixDashboard
@SpringBootApplication
@EnableHystrix
@EnableHystrixDashboard
public class ContestDemoApplication{
    public static void main(String[] args) {
        SpringApplication.run(ContestDemoApplication.class, args);
    }
}

[email protected]注解:

@HystrixCommand 加到服务的接口方法上,可以对接口限流。
下面的代码,给服务的 /hello接口 加了hystrix线程隔离,并且限制并发为5。
当接口熔断或者降级时,会走降级方法,降级方法将异常信息返回,并且返回状态码 503
@RestController
@RequestMapping(value = "/contest/demo")
public class HelloController {
    //对controller层的接口做hystrix线程池隔离,可以起到限流的作用
    @HystrixCommand(
            commandKey = "helloCommand",//缺省为方法名
        threadPoolKey = "helloPool",//缺省为类名
        fallbackMethod = "fallbackMethod",//指定降级方法,在熔断和异常时会走降级方法
        commandProperties = {
        //超时时间
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
},
        threadPoolProperties = {
                //并发,缺省为10
                @HystrixProperty(name = "coreSize", value = "5")
        }
    )
    @RequestMapping(
            value = "/hello",
            method = RequestMethod.GET
    )
    public String sayHello(HttpServletResponse httpServletResponse){
        return "Hello World!:00000";
    }

    /**
     *  降级方法,状态码返回503
     *  注意,降级方法的返回类型与形参要与原方法相同,可以多一个Throwable参数放到最后,用来获取异常信息
     */
    public String fallbackMethod(HttpServletResponse httpServletResponse,Throwable e){
        httpServletResponse.setStatus(HttpStatus.SERVICE_UNAVAILABLE.value());
        return e.getMessage();
    }
}

hystrix的属性配置:

如果将@HystrixCommand注解加到方法上,不对属性(如CoreSize)做任何配置,那么相当于使用了如下缺省配置。 每个属性的意义可以参考  hystrix学习资料
@HystrixCommand(
            commandProperties = {
                    //execution
                    @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),
                    @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
                    @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true"),
                    @HystrixProperty(name = "execution.isolation.thread.interruptOnCancel", value = "false"),
                    @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),
                    //fallback
                    @HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "10"),
                    @HystrixProperty(name = "fallback.enabled", value = "true"),
                    //circuit breaker
                    @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
                    @HystrixProperty(name = "circuitBreaker.forceClosed", value = "false"),
                    @HystrixProperty(name = "circuitBreaker.forceOpen", value = "false"),
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
                    //Metrics
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"),
                    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10"),
                    @HystrixProperty(name = "metrics.rollingPercentile.enabled", value = "true"),
                    @HystrixProperty(name = "metrics.rollingPercentile.timeInMilliseconds", value = "60000"),
                    @HystrixProperty(name = "metrics.rollingPercentile.numBuckets", value = "6"),
                    @HystrixProperty(name = "metrics.rollingPercentile.bucketSize", value = "100"),
                    @HystrixProperty(name = "metrics.healthSnapshot.intervalInMilliseconds", value = "500"),
                    //request context
                    @HystrixProperty(name = "requestCache.enabled", value = "true"),
                    @HystrixProperty(name = "requestLog.enabled", value = "true")},
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "10"),
                    @HystrixProperty(name = "maximumSize", value = "10"),
                    @HystrixProperty(name = "maxQueueSize", value = "-1"),
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "5"),
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "1"),
                    @HystrixProperty(name = "allowMaximumSizeToDivergeFromCoreSize", value = "false"),
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000"),
                    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10")
            }
    )
    如果要自定义这些属性,那么需要先了解下hystrix属性配置的优先级。

4 个不同优先级别的配置(优先级由低到高)。
全局配置属性:通过在配置文件中定义全局属性值, 在应用启动时或可用Spring Cloud Config和服务本身的动态刷新接口实现的动态刷新配置功能下, 可以实现对“全局默认值”的覆盖以及在运行期对“全局默认值”的动态调整。

如下是 threadpool 和 command下的属性全局配置,注意具体的配置都在  default  下
#hystrix全局属性配置
hystrix:
  threadpool:
    default: #对应@HystrixCommand注解中threadPoolKey的属性值,默认为default
      coreSize: 50 #线程池的核心线程数及并发执行的最大线程数
  command:
    default: #对应@HystrixCommand注解中commandKey的属性值,默认为default
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000 #执行超时时间
      fallback:
        isolation:
          semaphore:
            maxConcurrentRequests: 1000 #任意时间点允许的降级方法并发数。当请求达到或超过该设置值其余请求不会调用fallback而是直接被拒绝

实例默认值:通过代码为实例定义的默认值。 通过代码的方式为实例设置属性值来覆盖默认的全局配置。

示例如下:
@HystrixCommand(
            commandKey = "helloCommand",//缺省为方法名
        threadPoolKey = "helloPool",//缺省为类名
        fallbackMethod = "fallbackMethod",//指定降级方法,在熔断和异常时会走降级方法
        commandProperties = {
        //超时时间
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
},
        threadPoolProperties = {
                //并发,缺省为10
                @HystrixProperty(name = "coreSize", value = "5")
        }
    )
    @RequestMapping(
            value = "/hello",
            method = RequestMethod.GET
    )
    public String sayHello(HttpServletResponse httpServletResponse){
        return "Hello World!:00000";
    }

实例配置属性:通过配置文件来为指定的实例进行属性配置, 以覆盖前面的三个默认值。 它也可用Spring Cloud Config和服务本身的动态刷新接口实现的动态刷新配置功能,实现对具体实例配置的动态调整。

以示例代码中的 /hello 接口为例, commandKey=helloCommand   threadPoolKey=helloPool,那么对其的配置如下
#hystrix参数配置
hystrix:
  threadpool:
    helloPool:  #注解中的threadPoolKey属性值, 如有特殊配置不想使用defualt默认配置可自行添加
      coreSize: 20
  command:
    helloCommand:  #注解中的commandKey属性值,如有特殊配置不想使用默认配置可自行添加
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 4000 #执行超时时间
相关标签: hystrix