《SpringCloud專題17》-Hystrix熔斷器案例

熊貓IT學院發表於2020-11-22

1.高併發測試

上章在非高併發情形下,還能勉強滿足,但是在搞併發的情況下有些問題

1.1.Jmeter壓測測試

開啟Jmeter,來20000個併發壓死8001,20000個請求都去訪問paymentInfo_TimeOut服務
在這裡插入圖片描述
再來一個訪問
http://localhost:8001//payment/hystrix/ok/31

1.2.看演示結果

兩個都在轉圈圈

為什麼會被卡死

tomcat的預設工作執行緒數被打滿了,沒有多餘的執行緒來分解壓力和處理

1.3.Jmeter壓測結論

上面還只是服務提供者8001自己測試,假如此時外部的消費者80也來訪問,那消費者只能乾等,最終導致消費端80不滿意,服務端8001直接被拖死

2.看熱鬧不嫌棄事大,80新建加入

新建cloud-consumer-feign-hystrix-order80
在這裡插入圖片描述
POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.itxiongmao.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-comsumer-feign-hystrix-order80</artifactId>

    <dependencies>

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

        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>com.itxiongmao.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

        <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>
    </dependencies>
</project>

YML

server:
  port: 80

spring:
  application:
    name: cloud-comsumer-feign-hystrix-order80

eureka:
  client:
    service-url:
      # 叢集版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

主啟動

package com.itxiongmao;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @BelongsProject: springcloud2020
 * @BelongsPackage: com.itxiongmao
 * @CreateTime: 2020-11-22 13:01
 * @Description: TODO
 */
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderHystrixMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderHystrixMain80.class, args);
    }
}

業務類

package com.itxiongmao.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 * @BelongsProject: springcloud2020
 * @BelongsPackage: com.itxiongmao.service
 * @CreateTime: 2020-11-22 13:02
 * @Description: TODO
 */
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
public interface PaymentHystrixService {


    /**
     * 正常訪問
     *
     * @param id
     * @return
     */
    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfo_OK(@PathVariable("id") Integer id);

    /**
     * 超時訪問
     *
     * @param id
     * @return
     */
    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfo_TimeOut(@PathVariable("id") Integer id);

}

package com.itxiongmao.controller;

import com.itxiongmao.service.PaymentHystrixService;
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 javax.annotation.Resource;

@RestController
@RequestMapping("order")
public class OrderHyrixController {

    @Resource
    private PaymentHystrixService paymentHystrixService;


    @GetMapping("info/ok/{id}")
    public String paymentInfo_OK(@PathVariable("id") Integer id){
        String res = paymentHystrixService.paymentInfo_OK(id);
        System.out.println(res);
        return res;
    };

    @GetMapping("info/timeout/{id}")
    public String paymentInfo_timeout(@PathVariable("id") Integer id){
        String res = paymentHystrixService.paymentInfo_OK(id);
        System.out.println(res);
        return res;
    };

}

正常測試

http://localhost/order/info/ok/32
在這裡插入圖片描述
在這裡插入圖片描述

3.高併發測試

2w個執行緒壓8001,消費者80微服務再去訪問的OK服務8001地址: http://localhost/order/info/ok/32

消費者80,o(╥﹏╥)o

要麼轉圈圈
要麼消費端報超時錯誤

3.1.故障和導致現象

8001同一層次的其他介面被困死,因為tomcat執行緒池裡面的工作執行緒已經被擠佔完畢,80此時呼叫8001,客戶端訪問響應緩慢,轉圈圈

正因為有上述故障或不佳表現 才有我們的降級/容錯/限流等技術誕生

在這裡插入圖片描述

3.2.如何解決?解決的要求

超時導致伺服器變慢(轉圈)

超時不再等待

出錯(當機或程式執行出錯)

出錯要有兜底

解決

對方服務(8001)超時了,呼叫者(80)不能一直卡死等待,必須有服務降級
對方服務(8001)down機了,呼叫者(80)不能一直卡死等待,必須有服務降級
對方服務(8001)ok,呼叫者(80)自己有故障或有自我要求(自己的等待時間小於服務提供者)

相關文章