其他分享
首页 > 其他分享> > 服务熔断Hystrix高级

服务熔断Hystrix高级

作者:互联网

服务熔断Hystrix高级

1 前言#

2 Hystrix的监控平台#

2.1 概述#

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
package com.sunxiaping;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients //开启OpenFeign的支持
@EnableCircuitBreaker //开启Hystrix
public class Order9007Application {
    public static void main(String[] args) {
        SpringApplication.run(Order9007Application.class, args);
    }
}
# 配置hystrix
hystrix:
    command:
      default:
        execution:
          isolation:
            thread:
              timeoutInMilliseconds: 6000 # 默认的连接超时时间为1秒,如果1秒没有返回数据,就自动触发降级逻辑
feign:
  hystrix: # 开启Feign中的Hystrix
    enabled: true

# 暴露所有端点
management:
  endpoints:
    web:
      exposure:
        include: '*'

实时监控数据

2.2 搭建Hystrix DashBoard监控#

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</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>
package com.sunxiaping;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients //开启OpenFeign的支持
@EnableCircuitBreaker //开启Hystrix
@EnableHystrixDashboard // 激活仪表盘
public class Order9007Application {
    public static void main(String[] args) {
        SpringApplication.run(Order9007Application.class, args);
    }
}

搭建Hystrix DashBoard监控

2.3 断路器聚合监控Turbine#

2.3.1 概述#

Turbine

2.3.2 搭建Turbine Server#

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</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-turbine</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>org.sunxiaping</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hystrix_turbine7004</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</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-turbine</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
server:
  port: 7004

spring:
  application:
    name: service-turbine # 微服务的名称

# 配置 eureka
eureka:
  instance:
    # 主机名称:服务名称修改,其实就是向eureka server中注册的实例id
    instance-id: service-turbine:${server.port}
    # 显示IP信息
    prefer-ip-address: true
  client:
    service-url: # 此处修改为 Eureka Server的集群地址
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

turbine:
  # 要监控的微服务列表,多个用,隔开
  app-config: service-order
  cluster-name-expression: "'default'"
package com.sunxiaping.turbine;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;

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

hystrix dashboard Unable to connect to Command Metric Stream解决办法

package com.sunxiaping.config;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

3 断路器的状态#

3.1 概述#

断路器的状态

总结:

  • 1️⃣Hystrix正常启动的时候,断路器的状态是CLOSED状态(所有的请求都可以正常访问)。
  • 2️⃣默认情况下,当请求次数大于20次,且存在50%的失败概率的时候,将自动触发熔断,断路器的状态变为OPEN状态(所有的请求都会进入到降级方法中)。
  • 3️⃣默认情况下,会维持OPEN状态一段时间(5s),进入到半打开状态(尝试释放一个请求到远程微服务发起调用)。如果释放的请求可以正常访问,就会关闭断路器(断路器的状态由HALF_OPEN状态变为CLOSED状态)。如果释放的请求不能访问,则将状态由HALF_OPEN状态变为OPEN状态。

3.2 测试断路器的工作状态#

3.2.1 环境准备#

3.2.2 修改订单系统的逻辑#

package com.sunxiaping.order.controller;


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.sunxiaping.order.domain.Product;
import com.sunxiaping.order.feign.ProductFeignClient;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping(value = "/order")
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;

    @GetMapping(value = "/buy/{id}")
    @HystrixCommand(fallbackMethod = "orderFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"), //默认的连接超时时间为1秒,如果1秒内没有返回数据,自动触发降级逻辑
            
    })
    public Product buy(@PathVariable(value = "id") Long id) {
        if (1 != id) {
            throw new RuntimeException("服务器异常");
        }
        return restTemplate.getForObject("http://SERVICE-PRODUCT/product/findById/" + id, Product.class);
    }

    public Product orderFallback(Long id) {
        var product = new Product();
        product.setId(Long.MAX_VALUE);
        product.setProductName("******测试断路器的状态******");
        return product;
    }

}

3.2.3 修改Hystrix有断路器状态转化的阈值#

package com.sunxiaping.order.controller;


import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.sunxiaping.order.domain.Product;
import com.sunxiaping.order.feign.ProductFeignClient;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping(value = "/order")
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;

    @GetMapping(value = "/buy/{id}")
    @HystrixCommand(fallbackMethod = "orderFallback", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"), //默认的连接超时时间为1秒,如果1秒内没有返回数据,自动触发降级逻辑
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),  //是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"),   //触发熔断的最小请求次数,默认为20/10秒
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),  //熔断多少秒后去尝试请求,默认为10秒
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), //触发熔断的失败请求最小比例,默认为50%
    })
    public Product buy(@PathVariable(value = "id") Long id) {
        if (1 != id) {
            throw new RuntimeException("服务器异常");
        }
        return restTemplate.getForObject("http://SERVICE-PRODUCT/product/findById/" + id, Product.class);
    }

    public Product orderFallback(Long id) {
        var product = new Product();
        product.setId(Long.MAX_VALUE);
        product.setProductName("******测试断路器的状态******");
        return product;
    }

}
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000 # 默认的连接超时时间为1秒,如果1秒没有返回数据,就自动触发降级逻辑
      circuitBreaker:
        requestVolumeThreshold: 5 #触发熔断的最小请求次数,默认20/10秒
        sleepWindowInMilliseconds: 10000 #熔断多少秒后去尝试请求,默认为10秒
        errorThresholdPercentage: 50 #触发熔断的失败请求最小占比,默认50%

4 断路器的隔离策略#

线程池隔离 信号量隔离
线程 与调用线程非相同线程 与调用线程相同(jetty线程)
开销 排队、调度、上下文开销等 无线程切换,开销低
异步 可以是异步,也可以是同步。看调用的方法 同步调用,不支持异步
并发支持 支持(最大线程池大小hystrix.threadpool.default.maximumSize) 支持(最大信号量上限maxConcurrentRequests)
是否超时 支持,可直接返回 不支持,如果阻塞,只能通过调用协议(如:socket超时才能返回)
是否支持熔断 支持,当线程池到达maxSize后,再请求会触发fallback接口进行熔断 支持,当信号量达到maxConcurrentRequests后。再请求会触发fallback
隔离原理 每个服务单独用线程池 通过信号量的计数器
资源开销 大,大量线程的上下文切换,容易造成机器负载高 小,只是个计数器
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: ExecutionIsolationStrategy.SEMAPHORE # 信号量隔离
          maxConcurrentRequests: 5000  # 最大信号量上限
          # strategy: ExecutionIsolationStrategy.THREAD # 线程池隔离
https://www.cnblogs.com/xuweiweiwoaini/p/13764552.html

标签:hystrix,Hystrix,高级,springframework,熔断,import,org,cloud
来源: https://www.cnblogs.com/sunny3158/p/16656246.html