十、Hystrix 断路器(一)

1、概述

1)服务雪崩

多个微服务之间调用的时候,假设微服务A调用微服务B和C,微服务B和C又调用其他的微服务,这就是所谓的“扇出”。

如果扇出的链路上某个微服务的调用响应时间过长或者不可用,那么对微服务的调用就会占用越来越多的系统资源,从

而引起系统崩溃,这就是所谓的"雪崩效应“

对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源在几秒内饱和。比失败更糟糕的是这些应用程序还可能导致服务之间的延迟增加,

备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都预示着需要对故障和延迟进行隔离和管理,以便单个依赖的失败不能取消整个应用或者系统

clipboard

2)Hystrix 是什么

clipboard

2、Hystrix重要概念

1)服务降级

服务器忙,请稍后再试,不让服务器等待并立即返回一个友好提示 fallback

哪些情况会触发服务降级?

① 程序运行异常

② 超时

③ 服务熔断触发服务降级

④  线程池、信号量打满触发服务降级

2)服务熔断

达到最大服务访问后,直接拒绝访问,然后用服务降级的方式返回友好的提示

【注意】服务熔断后,会在请求并发量减少时,自动恢复链路

3)服务限流

秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行

3、Hystrix 案例实现

1)搭建服务提供者端:cloud-provider-hystrix-payment8001

① pom文件

<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><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </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>

② 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,http://eureka7002.com:7002/eureka
      defaultZone:  http://eureka7001.com:7001/eureka

③ 主启动类

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

④ 业务类 :

@RestController
@Slf4j
public class PaymentController {

    @Autowired
    private PaymentService paymentService;

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

    @GetMapping("/payment/hystrix/ok/{id}")
    public String paymentInfo_ok(@PathVariable("id") Integer id){

        String result = paymentService.paymentInfo_ok(id);
        log.info("*****************result************");
        return  result;
    }
    @GetMapping("/payment/hystrix/timeout/{id}")
    public String paymentInfo_timeout(@PathVariable("id") Integer id) throws InterruptedException {

        String result = paymentService.paymentInfo_timeout(id);
        log.info("*****************result************");
        return  result;
    }
}

@Service
public class PaymentService {
    
    public String paymentInfo_ok(Integer id){
        return "线程池:"+Thread.currentThread().getName()+
                " paymentInfo_ok,id:"+id+" O(∩_∩)O哈哈~";
    }
    public String paymentInfo_timeout(Integer id){
        int timenumber=5;
        try {
            TimeUnit.SECONDS.sleep(timenumber);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:"+Thread.currentThread().getName()+
                " paymentInfo_timeout,id:"+id+" 耗时3秒!!";
    }
}

⑤、jmeter压力测试

开启Jmeter,20000个并发,压测http://localhost:8001/payment/hystrix/timeout/1 接口,

然后去浏览器上访问 http://localhost:8001/payment/hystrix/timeout/1

访问会出现卡顿

2)服务消费方80加入 cloud-consumer-feign-hystrix-order80

①、pom文件 : 主要是hytrix和feign的依赖

<dependencies>
    <!--openfeign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--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>
    <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
    <dependency>
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </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>
</dependencies>

②、yml

server:
  port: 80
spring:
  application:
    name: cloud-consumer-order
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka

③、主启动类

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

④、业务类

@RestController
@Slf4j
public class OrderController {

    @Autowired
    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}")
    public String paymentInfo_timeout(@PathVariable("id") Integer id)
    {
        String result = paymentHystrixService.paymentInfo_timeout(id);
        return result;
    }
}
=========================================================================================
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")
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);
}

⑤、访问 http://localhost/consumer/payment/hystrix/ok/1 ,显示下图,说明远程调用成功

clipboard

⑥、

开启Jmeter,20000个并发,压测http://localhost:8001/payment/hystrix/timeout/1 接口,

然后去浏览器上访问 http://localhost/consumer/payment/hystrix/ok/1

访问会出现卡顿

3)上述结论

正是有了上述故障或不假表现,才有了我们降级、容错,限流的技术的产生

4)如何解决

① 服务提供方超时,调用者80不能一直卡死等待,必须要有服务降级

② 服务提供方宕机了,调用者不能一直处于卡死状态,必须要有服务降级

③ 服务提供者ok,调用者80自己出故障,自己要有服务降级

原文地址:https://www.cnblogs.com/houchen/p/14842875.html