【SpringCloud】Hystrix使用

Hystrix重要概念

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

  1. 服务降级:服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback
  2. 服务熔断:拉闸,服务的降级->进而熔断->恢复调用链路
  3. 服务限流:秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行

使用

POM

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

启动类

@EnableHystrix

YML

feign:
  hystrix:
    enabled: true

示例

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")

示例:没配置Hystrix的方法使用@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ㄒ)/~~";
    }
}

服务降级,客户端去调用服务端,碰上服务端宕机或关闭

异常:

  1. 运行
  2. 超时
  3. 宕机

接口Feign调用Service接口

@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);
}

Service实现类兜底,在Feign调用不成功时调用实现类中的方法

@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";
    }
}

此时服务端provider已经down后,但是我们做了服务降级处理,
让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器

服务熔断

服务的降级->进而熔断->恢复调用链路
当检测到该节点微服务调用响应正常后,恢复调用链路。
在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,
当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@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;
    }
}

@HystrixCommand中commandProperties参数

HystrixCommandProperties

Hystrix执行流程

在这里插入图片描述

服务监控hystrixDashboard

POM

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

HystrixDashboardMain9001+新注解@EnableHystrixDashboard
注意:

@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;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45742250/article/details/132340244