Hystrix基本使用

Hystrix基本使用

Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离、信号量隔离、降级策略、熔断技术。
在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等。我们要构建稳定、可靠的分布式系统,就必须要有这样一套容错方法

熔断触发降级

  • 熔断的目的是为了起到保护作用
  • 降级
    • 主动降级,大促的时候关闭非核心服务。
    • 被动降级,熔断降级、限流降级

降级

熔断是一种降级策略

一. 添加pom依赖

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

二. 在启动类上添加 @EnableCircuitBreaker注解,开启Hystrix熔断

@EnableCircuitBreaker
@ComponentScan(basePackages = {
    "com.gxedu.example.controller",
    "com.gxedu.example.sourceloader",
    "com.gxedu.example",
    "com.gxedu.springcloud.clients"})
@EnableFeignClients(basePackages = "com.gxedu.springcloud.clients")
@SpringBootApplication
public class UserServiceProviderApplication {

    public static void main(String[] args) {
        SpringApplication springApplication=new SpringApplication(UserServiceProviderApplication.class);
        Map<String,Object> map=new HashMap<>();
        map.put("key","value");
        springApplication.setDefaultProperties(map);
        springApplication.run(args);
    }

}

三. application.yml

spring:
  application:
    name: user-service
#  kafka:
#    bootstrap-servers: 192.168.216.128:9092
#    consumer:
#      group-id: user-service
  cloud:
    bus:
      enabled: false
server:
  port: 9999
management:
  endpoints:
    web:
      exposure:
        include: refresh,hystrix.stream
feign:
  hystrix:
    enabled: true  # 开启feign的hystrix支持,默认是false 
hystrix:
  command:
    default:  #全局配置,        (针对方法配置)feignclient#method(param)
      execution:
        timeout:
          enable: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000  #命令执行超时时间,默认1000ms,调接口响应时间超1S执行降级,不管提供者是否挂机还是延迟超过时间就走降级
    OrderServiceFeignClient#orders():
      execution:
        isolation:
          strategy: SEMAPHORE
          semaphore:
            maxConcurrentRequests: 10
    OrderServiceFeignClient#insert():
      execution:
        isolation:
          strategy: THREAD
  threadpool:
    order-service:
      coreSize: 2
      maxQueueSize: 1000
      queueSizeRejectionThreshold:  800
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000

四. Hystrix降级

Hystrix中的三种降级方案,fallback-> 回退方案(降级处理方案)

熔断触发降级

HystrixCommandProperties这个类中查询我们需要配置的参数

@RestController
public class HystrixController {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(commandProperties = {
        @HystrixProperty(name="circuitBreaker.enabled",value ="true"),
        @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "5"),
        @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),
        @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")
    },fallbackMethod = "fallback",
                    groupKey = "",threadPoolKey = "order-service")
    @GetMapping("/hystrix/order/{num}")
    public String queryOrder(@PathVariable("num")int num){
        if(num%2==0){
            return "正常访问";
        }
        //restTemplate默认有一个请求超时时间
        return  restTemplate.getForObject("http://localhost:8082/orders",String.class);
    }
    
    //配置降级的fallback方法,参数要和请求的方法参数一致
    public String fallback(int num){
        return "请求被降级";
    }
}
  • 熔断开启之后,后续的正常请求也无法发送过去.

  • 如何触发熔断?“判断阈值”

    10s钟之内,发起了20次请求,失败率超过50%。 熔断的恢复时间(熔断5s),从熔断开启 到后续5s之内的请求,都不会发起到远程服务端.

  • 熔断会有一个自动恢复。

@HystrixProperty(name=“circuitBreaker.enabled”,value =“true”), --开启状态

@HystrixProperty(name=“circuitBreaker.requestVolumeThreshold”,value = “5”), --最小请求次 数

@HystrixProperty(name=“circuitBreaker.sleepWindowInMilliseconds”,value = “5000”), --5s 熔断的时间

@HystrixProperty(name=“circuitBreaker.errorThresholdPercentage”,value = “50”) -百分比(50%)

开启熔断,在5s之内发起5次请求,失败率超过50%,自动触发熔断,5s之后会自动恢复

请求超时触发降级
/**
*  如果配置了超时时间,就使用自己的超时时间,execution.isolation.thread.timeoutInMilliseconds,3s超时
   结果: 正常访问返回
*/
@HystrixCommand(fallbackMethod ="timeoutFallback",commandProperties = {
    @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000"),
})
@GetMapping("/hystrix/timeout")
public String queryOrderTimeout(){
    return  restTemplate.getForObject("http://localhost:8082/orders",String.class);
}

/**
*  如果没有配置超时时间,就使用默认的全局配置的超时时间,在application.yml中配置,2s超时
* hystrix:
  command:
    default:  #全局配置, feignclient#method(param)
      execution:
        timeout:
          enable: true
        isolation:
          thread:
            timeoutInMilliseconds: 2000 
  结果: 超时被降级          
*/
@HystrixCommand(fallbackMethod ="timeoutFallback")
@GetMapping("/hystrix/timeout1")
public String queryOrderTimeout1(){
    return  restTemplate.getForObject("http://localhost:8082/orders",String.class);
}

public String timeoutFallback(){
    return "超时被降级";
}

/** 
*  调用http://localhost:8082/orders
*
*/
@RestController
public class OrderServiceImpl implements OrderService{

    @Override
    public String orders() {
        try {
            //伪代码,睡眠2s
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Return All Orders";
    }

    @Override
    public int insert(OrderDto dto) {
        return 1;
    }
}

修改接口超时间时间可以在user调用方修改yml 文件:

hystrix:
  command:
    default:  #全局配置, feignclient#method(param)
      execution:
        timeout:
          enable: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000  #命令执行超时时间,默认1000ms,调接口响应时间超1S执行降级,不管提供者是否挂机还是延迟超过时间就走降级
资源隔离触发降级
线程池隔离(默认是线程池隔离)
@HystrixCommand(
    groupKey="order-service",
    commandKey = "queryOrder",
    threadPoolKey="order-service",
    threadPoolProperties = {
        @HystrixProperty(name = "coreSize", value = "30"),//线程池大小
        @HystrixProperty(name = "maxQueueSize", value = "100"),//最大队列长度
        @HystrixProperty(name = "keepAliveTimeMinutes", value ="2"),//线程存活时间
        @HystrixProperty(name = "queueSizeRejectionThreshold", value= "15")//拒绝请求
    },
	fallbackMethod = "fallback")
信号量隔离
/**
* 信号量隔离实现
* 不会使用Hystrix管理的线程池处理请求。使用容器(Tomcat)的线程处理请求逻辑。
* 不涉及线程切换,资源调度,上下文的转换等,相对效率高。
* 信号量隔离也会启动熔断机制。如果请求并发数超标,则触发熔断,返回fallback数据。
* commandProperties - 命令配置,HystrixPropertiesManager中的常量或字符串来配置。
* execution.isolation.strategy - 隔离的种类,可选值只有THREAD(线程池隔离)和 SEMAPHORE(信号量隔离)。
* 默认是THREAD线程池隔离。
* 设置信号量隔离后,线程池相关配置失效。
* execution.isolation.semaphore.maxConcurrentRequests - 信号量最大并发数。默认值是10。常见配置500~1000。
* 如果并发请求超过配置,其他请求进入fallback逻辑。
*/
@HystrixCommand(fallbackMethod="semaphoreQuarantineFallback",
commandProperties={
    @HystrixProperty(
    name=HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,value="SEMAPHORE"), // 信号量隔离
    @HystrixProperty(
    name=HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS,value="100") // 信号量最大并发数
}
在配置文件中配置单个接口的信号量隔离和线程池隔离
hystrix:
  command:
    default:  #全局配置, feignclient#method(param)
      execution:
        timeout:
          enable: true
        isolation:
          thread:
            timeoutInMilliseconds: 3000 #命令执行超时时间,默认1000ms,调接口响应时间超过2S就执行降级,不管提供者是否挂机还是延迟超过时间就走降级
    OrderServiceFeignClient#orders():
      execution:
        isolation:
          strategy: SEMAPHORE  
          semaphore:
            maxConcurrentRequests: 10
    OrderServiceFeignClient#insert():
      execution:
        isolation:
          strategy: THREAD
  threadpool:
    order-service:
      coreSize: 2
      maxQueueSize: 1000
      queueSizeRejectionThreshold:  800

五. Fegin集成Hystirx

HystrixFeignController
@RestController
public class HystrixFeignController {

    @Autowired
    OrderServiceFeignClient orderServiceFeignClient;

    @GetMapping("/hystrix/feign/order")
    public String queryOrder(){
        return orderServiceFeignClient.orders();
    }

    @PostMapping("/hystrix/feign/order")
    public String insertOrder(){
        OrderDto orderDto=new OrderDto();
        orderDto.setOrderId("GP0001");
        return orderServiceFeignClient.insert(orderDto)>0?"SUCCESS":"FAILED";
    }
}
OrderServiceFeignClient

在@FeignClient注解里边配置fallback接口的降级方法

@FeignClient(value = "order-service",fallback = OrderServiceFeignClient.OrderServiceFeignClientFallback.class)
public interface OrderServiceFeignClient extends OrderService{

    @Component
    class OrderServiceFeignClientFallback implements OrderServiceFeignClient{

        @Override
        public String orders() {
            System.out.println("查询订单失败,请稍候重试");
            return "查询订单失败,请稍候重试";
        }

        @Override
        public int insert(OrderDto dto) {
            System.out.println("insert失败");
            return -1;
        }
    }
}

public interface OrderService {

    @GetMapping("/orders")
    String orders();

    @PostMapping("/order")
    int insert(OrderDto dto);
}

@RestController
public class OrderServiceImpl implements OrderService{

    @Override
    public String orders() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Return All Orders");
        return "Return All Orders";
    }

    @Override
    public int insert(OrderDto dto) {
        return 1;
    }
}
application.yml
hystrix:
  command:
    default:  #全局配置, feignclient#method(param)
      execution:
        timeout:
          enable: true
        isolation:
          thread:
            timeoutInMilliseconds: 2000 #命令执行超时时间,默认1000ms,调接口响应时间超过2S就执行降级,不管提供者是否挂机还是延迟超过时间就走降级
    OrderServiceFeignClient#orders():  # 单独配置 feignclient#method(param)
      execution:
        isolation:
          strategy: SEMAPHORE  # 信号量隔离
          semaphore:
            maxConcurrentRequests: 10
    OrderServiceFeignClient#insert():
      execution:
        isolation:
          strategy: THREAD  # 线程池隔离
  threadpool:
    order-service:
      coreSize: 2
      maxQueueSize: 1000
      queueSizeRejectionThreshold:  800
信号量隔离测试

用Jmeter压测,1s中发送50个请求

在Order-service中只有10个请求是成功的,其他都走降级策略

线程池隔离测试
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值