SpringCloud之Hystrix

Hystrix 介绍 详解,服务降级,熔断,限流
这里写图片描述
服务雪崩效应–级联效应
服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过 程,就叫服务雪崩效应
导致雪崩效应的最根本原因是: 大量请求线程同步等待造成的资源耗尽

解决方案
1. 超时机制
2. 服务限流
3. 服务熔断
4. 服务降级

在整个SpringCloud构建微服务的体系中,有一个提供超时机制,限流,熔断,降级最全面 的实现:Hystrix(豪猪) 翻译过来表示:自身带刺,有自我保护的意思,外国人起名字还是 很有意思滴。当然Hystrix并不是Spring的,而是NetFlix公司开源的。那么Spring只是把它 拿过来,在他的基础上面做了一些封装,然后加入到了SpringCloud中,实现高可用的分布 式微服务架构

引入hystrix
这里写图片描述
@HystrixCommond
@EnableCircuitBreaker

那么Hystrix是怎么做到降级的呢? 他通过一种叫做“命令模式”的方式,继承(HystrixCommand类)来包裹具体的服务调用 逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback),见 (OrderServiceCommand类)
这里写图片描述
降级(报错,超时)
fallback fallbackMethod,返回静态的信息.备用接口/缓存/mock数据

熔断fusing
重试次数,自动恢复时间,可以再yml中配置的
测试报错和正常的情况,我们可以看到当报错达到一定阈值时,会自动熔断,阈值可以配
置,如下: 一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发
circuit break。默认20 hystrix.command.default.circuitBreaker.requestVolumeThreshold # 触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内都会拒 绝request,也就是5000毫秒后才会关闭circuit。默认5000 hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds

限流
配置线程组 线程池,队列 默认是10个线程

fallback的数据会统计在Metrics中,就是配置熔断的时候使用

用JMeter做压测

@HystrixCommand(fallbackMethod = “findByIdFallback”)

@RestController
public class OrderController {
  private static final Logger logger =
   LoggerFactory.getLogger(OrderController.class);
  @Autowired
  private RestTemplate restTemplate;

  @HystrixCommand(fallbackMethod = "findByIdFallback")
  @GetMapping("/user/{id}")
  public User findById(@PathVariable Long id) {
    logger.info("================请求用户中心接口==============");
    return this.restTemplate.getForObject(
    "http://microservice-provider-user/" + id, User.class);
  }

  public User findByIdFallback(Long id) { 
    User user = new User();
    user.setId(-1L);
    user.setName("默认用户");
    return user;
  }

}
@EnableDiscoveryClient
@SpringBootApplication
@EnableCircuitBreaker
public class ConsumerOrderApplication {
  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

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

降级配置

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-order
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
hystrix:
  command:
    default:
      circuitBreaker:
        requestVolumeThreshold: 1
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 4000

UserController

@RestController
public class UserController {

  private final Logger logger = Logger.getLogger(getClass());

  @Autowired
  private UserRepository userRepository;
  @Autowired
  private Registration registration;


  @GetMapping("/{id}")
  public User findById(@PathVariable Long id) throws Exception {
      logger.info("用户中心接口:查询用户"+ id +"信息");
      /*//测试超时触发降级
      int sleepTime = new Random().nextInt(2000);
      logger.info("sleepTime:" + sleepTime);
      Thread.sleep(sleepTime);  */

      /*//测试熔断,传入不存在的用户id模拟异常情况
      if (id == 10) {
        throw new NullPointerException();
      }*/

      //测试限流,线程资源隔离,模拟系统执行速度很慢的情况
     // Thread.sleep(3000);

      User findOne = userRepository.findOne(id);
      return findOne;
  }

  @GetMapping("/getIpAndPort")
  public String findById() {
      return registration.getHost() + ":" + registration.getPort();
  }
}

熔断配置

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-order
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
hystrix:
  command:
    default:
      circuitBreaker:
        requestVolumeThreshold: 3 #次数
        sleepWindowInMilliseconds: 10000  #时间

限流,超时模拟

测试限流,线程资源隔离,模拟系统执行速度很慢的情况
 Thread.sleep(3000);
server:
  port: 8010
spring:
  application:
    name: microservice-consumer-order
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 20000

配置线程池线程组
参数queueSizeRejectionThreshold 和maxQueueSize 。queueSizeRejectionThreshold默认值是5,允许在队列中的等待的任务数量,超过线程组配置大小的请求直接降级,优先输出,返回结果

@RestController
public class OrderController {
    private static final Logger 
    logger=LoggerFactory.getLogger(OrderController.class);
    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "findByIdFallback", 
                    groupKey = "orderUserGroup", 
                    threadPoolKey = "orderUserIdThreadPool", 
                    threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "2"), 
                    @HystrixProperty(name ="queueSizeRejectionThreshold",
                     value = "1") })
    @GetMapping("/user/{id}")
    public User findById(@PathVariable Long id) {
        logger.info("==============");
        "http://microservice-provider-user/" + id, User.class); 
    }
    public User findByIdFallback(Long id) {
        User user = new User();
        user.setId(-1L);
        user.setName("默认用户");
        return user;
    }
}

引入依赖

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

猜你喜欢

转载自blog.csdn.net/qyj19920704/article/details/80562130
今日推荐