Microservices: Springboot integrates Hystrix to achieve fusing, downgrading, and isolation

foreword

In distributed microservice projects, multiple services are often reused, resulting in multiple service calls. For example, service A calls service B, and service B calls service C. A long service call link will inevitably increase the probability of service timeout. Service timeout blocking will always occupy thread resources. A large number of blocks will directly consume service threads. In severe cases, the service will directly crash and cause the call link service avalanche. So, is there a way to achieve service fusing, reduction, and isolation? Today we introduce the Hystrix framework developed by Netflix.

knowledge accumulation

Hystrix is ​​a latency and fault tolerance library designed to isolate access points to remote systems, services, and third-party libraries, stop cascading failures, and achieve resilience in complex distributed systems where failures are inevitable.

Service fusing is an operation that actively disconnects when the service reaches certain specific indicators, while service degradation is to evaluate subsequent services during the service call process. For example, if there is no response after reaching the timeout period, subsequent redundant logic processing will be performed. If the service is broken, the service will be downgraded, but the downgrade of the service is not necessarily the trigger of the service fuse.

Service avalanche refers to link calls made by multiple services in the business process. If the subsequent link service fails and blocks, it will affect the blocking of the caller's service. In severe cases, the entire link service will be directly dragged to death, resulting in a service avalanche.

Hystrix provides two isolation modes: semaphore and thread. Semaphore isolation can directly limit the number of concurrent threads of the service, while thread isolation directly relies on the thread pool to limit the current load to directly use the current thread pool thread, so as to avoid the situation that the service is unavailable due to other threads that consume the service. By default, Hystrix uses thread isolation, which is the real service isolation.

In actual project development, Hystrix and openfeign can be integrated friendly. We can directly introduce Hystrix and feign dependencies in Springboot and spring cloud projects, and complete the corresponding configuration to achieve the results we need.

Springboot integrates Hystrix

In the development of microservices, in order to reuse and call each other between services, we need to introduce a registration center to help realize the publishing, subscription and maintenance of services. There are nacos, consul, etc. for the middleware of the registration center, among which the construction is relatively simple and will not be described here.

When we introduce the registration center, we can use the feign framework to directly call the service through the RestTemplate. We no longer care about how to call it internally, but only need to encapsulate the interface according to specific rules.

The following focuses on the integration and configuration of Hystrix

1. Maven dependency import

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
    <relativePath/>
</parent>
<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
</properties>
<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>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2. The application enables feign's hystrix support (client configuration current limiting and downgrading fuse)

#hystrix
feign:
  hystrix:
    enabled: true
  circuitbreaker:
    enabled: true

hystrix:
  threadpool:
    #默认配置
    default:
      #动态调整线程数
      allowMaximumSizeToDivergeFromCoreSize: false
      #核心线程数
      coreSize: 10
      #最大线程数
      maximumSize: 10
      #空闲存活时间min
      keepAliveTimeMinutes: 1
      #队列长度 设置置为-1时,队列会使用 SynchronousQueue,此时其 size 为0,Hystrix 不会向队列内存放作业。
      maxQueueSize: -1
      #如果需要动态修改队列长度的话可以设置此值,即使队列未满,队列内作业达到此值时同样会拒绝请求。此值默认是 5
      queueSizeRejectionThreshold: 5
  command:
    default:
      #线程池key
      threadPoolKeyOverride: default
      #熔断器
      circuitBreaker:
        enabled: true
        #错误占比
        errorThresholdPercentage: 50
        #窗口时间内最小请求数目
        requestVolumeThreshold: 20
        #休眠时间
        sleepWindowInMilliseconds: 5000
      execution:
        #隔离
        isolation:
          strategy: THREAD
          thread:
            #线程超时时间
            timeoutInMilliseconds: 5000
        timeout:
          enabled: true
      #统计器
      metrics:
        rollingStats:
          #窗口大小
          timeInMilliseconds: 10000
          #桶数目需要保证与timeInMilliseconds整除
          numBuckets: 10

3. Add @EnableFeignClients @EnableHystrix to the entry class to enable feign and hystrix

@EnableFeignClients
@EnableHystrix
@Slf4j
public class TestDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestDemoApplication.class, args);
    }
}

4. Feign call to add downgrade method

/**
 * @author senfel
 * @version 1.0
 * @date 2023/7/03 15:04
 */
@Service
@FeignClient(value = "test-demo",fallback = FallbackService.class)
public interface TestService {

    /**
     * 测试hystrix
     */
    @GetMapping("/feign")
    String feign(@RequestParam String str);


}
/**
 * FallbackService
 * @author senfel
 * @version 1.0
 * @date 2023/7/3 15:26
 */
@Service
public class FallbackService implements TestService {

    @Override
    public String feign(String str) {
        return ">>>>>客户端服务降级>>>>>";
    }
}

Server-side configuration current limiting downgrade circuit breaker (choose to use)

Thread isolation,
service call timeout 5s downgrade,
at least 20 requests within 10s enter the rules to verify that the error rate exceeds 50%, and the error rate is directly fused for 5s

@GetMapping("/feign")
@HystrixCommand(
        // 标识线程池 保持唯一
        threadPoolKey = "threadPoolKeyByFeign",
        // 线程池细节属性配置
        threadPoolProperties = {
                // 线程数
                @HystrixProperty(name="coreSize",value = "10"),
                //最大线程数量
                @HystrixProperty(name="maximumSize",value = "10"),
                // 等待队列长度
                @HystrixProperty(name="maxQueueSize",value="-1"),
                //如果需要动态修改队列长度的话可以设置此值,即使队列未满,队列内作业达到此值时同样会拒绝请求。此值默认是 5
                @HystrixProperty(name="queueSizeRejectionThreshold",value="5"),
                //空闲时间1min
                @HystrixProperty(name="keepAliveTimeMinutes",value="1")
        },
        // 熔断的一些细节属性配置
        commandProperties = {
                // 调用服务超时时间
                @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000"),
                // 统计时间窗口定义
                @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "10000"),
                //桶数量 保证与统计时间窗口整除
                @HystrixProperty(name = "metrics.rollingPercentile.numBuckets",value = "10"),
                // 统计时间窗口内的最小请求数
                @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "20"),
                // 统计时间窗口内的错误数量百分比阈值
                @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
                // 自我修复时的活动窗口长度
                @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000")
        },
        // 降级方法
        fallbackMethod = "myFallBack"
)
public String feign(String str){
    if(str.contains("s")){
        throw new RuntimeException();
    }
    return str+"ssss";
}

private String myFallBack(String str){
    return ">>>>>服务端服务降级>>>>>";
}

Springboot integrates Hystrix visualization

1. Increase maven dependency

<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-dashboard</artifactId>
</dependency>

2. Application configuration monitoring

hystrix:
  dashboard:
    proxy-stream-allow-list: "127.0.0.1"
    
management:
  endpoints:
    web:
      exposure:
        include: health,hystrix.stream    

3. Page access hystrix-dashboard

http://127.0.0.1:9999/hystrix
insert image description here

http://127.0.0.1:9999/actuator/hystrix.stream
insert image description here

write at the end

Springboot integrates Hystrix to achieve fusing, degradation, and isolation is relatively simple, and provides a hystrix-dashboard visual dashboard. The Hystrix framework has implemented circuit breaker downgrade and isolation strategies. After integration, we only need to configure and select according to our own situation. Generally, in the microservice architecture, the client fuse downgrade is preferred. Of course, annotation configuration can also be performed on the server side.

Guess you like

Origin blog.csdn.net/weixin_39970883/article/details/131527703