[Spring Cloud] Hystrix use

Hystrix important concepts

https://github.com/Netflix/Hystrix/wiki/How-To-Use
https://github.com/Netflix/Hystrix

  1. Service degradation: The server is busy, please try again later, do not let the client wait and return a friendly prompt immediately, fallback
  2. Service circuit breaker: shut down, service downgrade -> then circuit breaker -> restore the call link
  3. Service current limit: Flash kill high concurrency and other operations, it is strictly forbidden to rush over and crowd, everyone queues up, N per second, and proceeds in an orderly manner

use

POM

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

Startup class

@EnableHystrix

YML

feign:
  hystrix:
    enabled: true

Example

package com.atguigu.springcloud.service;

import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class PaymentService
{
    
    
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
    
    
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")
    })
    public String paymentInfo_TimeOut(Integer id)
    {
    
    
        //int age = 10/0;
        try {
    
     TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) {
    
     e.printStackTrace(); }
        return "线程池:  "+Thread.currentThread().getName()+"success";
    }
    public String paymentInfo_TimeOutHandler(Integer id)
    {
    
    
        return "线程池:  "+Thread.currentThread().getName()+"business"+id;
    }

    //=====服务熔断
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
    
    
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少后跳闸
    })
    public String paymentCircuitBreaker(@PathVariable("id") Integer id)
    {
    
    
        if(id < 0)
        {
    
    
            throw new RuntimeException("******id 不能负数");
        }
        String serialNumber = IdUtil.simpleUUID();

        return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
    }
    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id)
    {
    
    
        return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~   id: " +id;
    }

}

Global fallback

@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")

Example: If Hystrix is ​​not configured, use the method in @DefaultProperties

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystirxController
{
    
    
    @Resource
    private PaymentHystrixService paymentHystrixService;

    @GetMapping("/consumer/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id)
    {
    
    
        String result = paymentHystrixService.paymentInfo_OK(id);
        return result;
    }

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
    
    
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
    })
    //@HystrixCommand
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
    {
    
    
        int age = 10/0;
        String result = paymentHystrixService.paymentInfo_TimeOut(id);
        return result;
    }
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
    {
    
    
        return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";
    }

    // 下面是全局fallback方法
    public String payment_Global_FallbackMethod()
    {
    
    
        return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~";
    }
}

The service is degraded. The client calls the server and the server is down or shut down.

abnormal:

  1. run
  2. time out
  3. Downtime

The interface Feign calls the Service interface

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = PaymentFallbackService.class)
public interface PaymentHystrixService
{
    
    
    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}

The Service implementation class covers all the details and calls the methods in the implementation class when the Feign call is unsuccessful.

@Component
public class PaymentFallbackService implements PaymentHystrixService
{
    
    
    @Override
    public String paymentInfo_OK(Integer id)
    {
    
    
        return "-----PaymentFallbackService fall";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id)
    {
    
    
        return "-----PaymentFallbackService fall TimeOut";
    }
}

At this time, the server provider has been down, but we have done a service downgrade process,
so that the client will also get a prompt message when the server is unavailable without hanging and consuming the server

Service circuit breaker

Service degradation -> then circuit breaker -> restore the call link.
When it is detected that the node microservice call response is normal, the call link is restored.
In the Spring Cloud framework, the circuit breaker mechanism is implemented through Hystrix. Hystrix will monitor the status of calls between microservices.
When failed calls reach a certain threshold, the default is 20 failed calls within 5 seconds, the circuit breaker mechanism will be activated. The annotation of the circuit breaker mechanism is @HystrixCommand.

@Service
public class PaymentService
{
    
    	
	//=====服务熔断
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
    
    
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少后跳闸
    })
    public String paymentCircuitBreaker(@PathVariable("id") Integer id)
    {
    
    
        if(id < 0)
        {
    
    
            throw new RuntimeException("******id 不能负数");
        }
        String serialNumber = IdUtil.simpleUUID();

        return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
    }
    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id)
    {
    
    
        return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~   id: " +id;
    }
}

commandProperties parameter in @HystrixCommand

Find HystrixCommandPropertiescategory

Hystrix execution process

Insert image description here

Service monitoring hystrixDashboard

POM

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

HystrixDashboardMain9001+new annotation @EnableHystrixDashboard
Note:

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001
{
    
    
    public static void main(String[] args) {
    
    
            SpringApplication.run(PaymentHystrixMain8001.class, args);
    }


    /**
     *此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
     *ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
     *只要在自己的项目里配置上下面的servlet就可以了
     */
    @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;
    }
}

Guess you like

Origin blog.csdn.net/qq_45742250/article/details/132340244