欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Hystrix(一)---服务降级(基础案例)

程序员文章站 2022-04-15 23:16:53
一,高并发测试模块生产者8001的pom.xml org.springframework.cloud spring-cloud-starter-netflix-hystrix...

一,高并发测试

模块生产者8001的pom.xml

<dependencies>
        <!--hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>

application.yml

server:
  port: 8001

spring:
  application:
    name: cloud-provider-hystrix-payment

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

PaymentService

@Service
public class PaymentService {

    //正常访问
    public String paymentIndo_OK(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "paymentIndo_OK,id" + id + "\t" + "O(∩_∩)O哈哈~";
    }
    //延时访问
    public String paymentIndo_TimeOut(Integer id) {
        try {
            TimeUnit.SECONDS.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "paymentIndo_TimeOut,id" + id + "\t" + "O(∩_∩)O哈哈~";
    }
}

PaymentController

@RestController
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String serverport;

    @GetMapping("/payment/htstrix/ok/{id}")
    public String paymentIndo_OK(@PathVariable("id") Integer id){
        String s = paymentService.paymentIndo_OK(id);
        return s;
    }

    @GetMapping("/payment/htstrix/timeout/{id}")
    public String paymentIndo_TimeOut(@PathVariable("id") Integer id){
        String s = paymentService.paymentIndo_TimeOut(id);
        return s;
    }
}

启动类PaymentHystrixMain8001

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

模块消费者80的PaymentHystrixService

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {

    @GetMapping("/payment/htstrix/ok/{id}")
    public String paymentIndo_OK(@PathVariable("id") Integer id);

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

模块消费者80的OrderHystrixController

@RestController
public class OrderHystrixController {

    @Resource
    private PaymentHystrixService paymentHystrixService;

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

    @GetMapping("/consumer/payment/htstrix/timeout/{id}")
    public String paymentIndo_TimeOut(@PathVariable("id") Integer id){
        String s = paymentHystrixService.paymentIndo_TimeOut(id);
        return s;
    }
 }
Jmeter测试

几万个并发,请求生产者8001都去访问paymentIndo_TimeOut,再访问一个http://localhost:8001/payment/htstrix/ok/2

Jmeter结论

生产者8001自己测试,消费者80也同时访问,消费者只能等待

导致原因

8001同一层次的其它接口服务被困死,因为tomcat线程池里面的工作线程已经被挤占完毕,80此时调用8001,客户端访问响应缓慢

解决办法
  • 对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
  • 对方服务(8001)down机了,调用者(80)不能一直卡死等待,必须有服务降级
  • 对方服务(8001)OK,调用者(80)自己出故障或有自我要求( 自己的等待时间小于服务提供者)

二,服务降级

1.8001fallback

修改8001的PaymentService的paymentIndo_TimeOut方法

//降级配置
@HystrixCommand(fallbackMethod = "paymentIndo_TimeOutHandler",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
    })
    public String paymentIndo_TimeOut(Integer id) {
        try {
            TimeUnit.SECONDS.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "paymentIndo_TimeOut,id" + id + "\t" + "O(∩_∩)O哈哈~";
    }

    public String paymentIndo_TimeOutHandler(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "paymentIndo_TimeOutHandler,id" + id + "\t" + "O(∩_∩)O嘿嘿~";
    }

添加8001的主启动类的注解(主启动类激活)

@EnableCircuitBreaker

2.80fallback

80的application.xml添加配置

feign:
  hystrix:
    enabled: true

添加80的主启动类的注解(主启动类激活)

@EnableHystrix

更改80的OrderHystrixController

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
    })
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
    {
        String result = paymentHystrixService.paymentIndo_TimeOut(id);
        return result;
    }
    public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id)
    {
        return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o";
    }
出现问题
  • 这时候每一个业务方法都要有一个备用方法,代码膨胀
  • 统一和自定义分开

更改80的OrderHystrixController

类上加上注解

@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")

更改方法paymentInfo_TimeOut

@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
    {
        String result = paymentHystrixService.paymentIndo_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ㄒ)/~~";
    }

Hystrix(二)—服务熔断(基础案例)

本文地址:https://blog.csdn.net/qq_43959546/article/details/107354540