Hystrix断路器入门1

1、分布式系统面临的问题

复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。

服务雪崩

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。

对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。

2、Hystrix概述

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

主要作用

  1. 服务降级
  2. 服务熔断
  3. 接近实时的监控

官方网址:https://github.com/Netflix/Hystrix/wiki/How-To-Use

3、Hystrix重要概述

3.1、服务降级(fallback)

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

常见出现情况
  1. 程序运行异常
  2. 超时
  3. 服务熔断触发服务降级
  4. 线程池、信号量打满也会导致服务降级

3.2、服务熔断(break)

类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示

服务的降级->进而熔断->恢复调用链路

3.3、服务限流(flowlimit)

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

4、Hystrix实战案例

4.1、实战项目搭建

1、将Eureka7001服务中心恢复单机版不要集群

在YAML配置文件里面修改注册地址

2、项目模块cloud-provider-hystrix-payment8001

  1. 添加依赖pom.xml文件

    <?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>springcloud2022</artifactId><groupId>com.zcl.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-provider-hystrix-payment8001</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><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.zcl.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>
    </project>
    
  2. YAML配置文件

    server:port: 8001spring:application:name: cloud-provider-hystrix-paymenteureka:client:register-with-eureka: truefetch-registry: trueservice-url:#defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eurekadefaultZone: http://eureka7001.com:7001/eureka
    

    使用单节点注册,暂时不使用集群部署

  3. 创建主启动类

    需要注册进Eureka服务中心一定要使用@EnableEurekaClient注解

    package com.zcl.springcloud;import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;/*** 描述:服务降级启动类** @author zhong* @date 2022-09-19 16:21*/
    @SpringBootApplication
    @EnableEurekaClient
    public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class, args);}
    }
    
  4. 业务实现

    接口

    package com.zcl.springcloud.service;/*** 描述:业务接口** @author zhong* @date 2022-09-19 16:24*/
    public interface PaymentService {/*** 正常访问接口* @param id* @return*/String paymentInfo_OK(Integer id);/*** 超时访问,演示降级* @param id* @return*/String paymentInfo_TimeOut(Integer id);
    }

    接口实现

    package com.zcl.springcloud.service.Impl;import com.zcl.springcloud.service.PaymentService;
    import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;/*** 描述:** @author zhong* @date 2022-09-19 16:25*/
    @Service
    public class PaymentServiceImpl implements PaymentService {/*** 正常访问* @param id* @return*/@Overridepublic String paymentInfo_OK(Integer id) {return "线程池:"+Thread.currentThread().getName()+"paymentInfo_OK,id: "+id+"\t"+"O(∩_∩)O";}/*** 超时演示,服务降级* @param id* @return*/@Overridepublic String paymentInfo_TimeOut(Integer id) {try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }return "线程池:"+Thread.currentThread().getName()+"paymentInfo_TimeOut,id: "+id+"\t"+"O(∩_∩)O,耗费3秒";}
    }
    
  5. 控制器的编写

    package com.zcl.springcloud.controller;import com.zcl.springcloud.service.Impl.PaymentServiceImpl;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 描述:暴露控制器** @author zhong* @date 2022-09-19 16:28*/
    @Slf4j
    @RestController
    public class PaymentController {/*** 注入业务接口*/@Resourceprivate PaymentServiceImpl paymentService;/*** 获取服务端口号*/@Value("${server.port}")private String serverPort;/*** 正常访问返回接口* @param id* @return*/@GetMapping("/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentService.paymentInfo_OK(id);log.info("****result: "+result);return result;}/*** 演示连接超时接口* @param id* @return* @throws InterruptedException*/@GetMapping("/payment/hystrix/timeout/{id}")public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException{String result = paymentService.paymentInfo_TimeOut(id);log.info("****result: "+result);return result;}
    }
    

3、启动测试

  1. 启动7001访问注册中心

  2. 启动cloud-provider-hystrix-payment8001

  3. 访问成功的接口:http://localhost:8001/payment/hystrix/ok/1

  4. 访问超时接口:http://localhost:8001/payment/hystrix/timeout/10

  5. 上面两个接口都正常说明都模块构建没有问题了

    以上述为根基平台,从正确->错误->降级熔断->恢复

4.2、高并发测试实战项目

高并发测试软件使用Apache JMeter(5.4.1)

  1. 定义并发数

  2. 定义http请求

    小技巧,通过右键HTTP请求可以添加汇报结果观察结果树来查看高并发的结果

  3. 压测开启后访问正常返回的接口:http://localhost:8001/payment/hystrix/ok/10

    正常的接口由原来的秒回响应也被拖累了,也会出现一些停顿

    tomcat的默认的工作线程数被打满 了,没有多余的线程来分解压力和处理。导致原来秒回的服务被拖累

  4. 结论

    上面还是服务提供者8001自己测试,假如此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80不满意,服务端8001直接被拖死

1、新建模块cloud-consumer-feign-hystrix-order80加入高并发测试

1.1、添加依赖pom.xml

<?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>springcloud2022</artifactId><groupId>com.zcl.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-consumer-feign-hystrix-order80</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><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.zcl.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></project>

1.2、添加yaml配置文件

server:port: 80eureka:client:register-with-eureka: falseservice-url:defaultZone: http://eureka7001.com:7001/eureka/

注意:上面的配置没有进行超时控制,如果访问的接口请求大于1秒就会报错超时,添加如下时间控制解决

#设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间ReadTimeout: 5000#指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeout: 5000

1.3、添加启动类

因为要远程调用服务提供者8001,通过@EnableFeignClients注解开启

package com.zcl.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;/*** 描述:hystrix消费者启动类** @author zhong* @date 2022-09-19 19:20*/
@SpringBootApplication
@EnableFeignClients
public class OrderHystrixMain80 {public static void main(String[] args) {SpringApplication.run(OrderHystrixMain80.class, args);}
}

1.4、业务类实现

远程调用接口

调用指定微服务下的两个请求接口,微服务通过了请求IP地址和端口号

package com.zcl.springcloud.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;/*** 描述:调用微服务接口** @author zhong* @date 2022-09-19 19:24*/
@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* @throws InterruptedException*/@GetMapping("/payment/hystrix/timeout/{id}")String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}

控制器创建

package com.zcl.springcloud.controller;import com.zcl.springcloud.service.PaymentHystrixService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 描述:消费者调用提供者控制器** @author zhong* @date 2022-09-19 19:27*/
@Slf4j
@RestController
public class OrderHystirxController {/*** 注入Feign业务接口*/@Resourceprivate PaymentHystrixService paymentHystrixService;/*** 远程调用微服务正常的接口* @param id* @return*/@GetMapping("/consumer/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentHystrixService.paymentInfo_OK(id);return result;}/*** 远程调用微服务睡眠三秒的接口* @param id* @return*/@GetMapping("/consumer/payment/hystrix/timeout/{id}")public String paymentInfo_TimeOut(@PathVariable("id") Integer id){String result = paymentHystrixService.paymentInfo_TimeOut(id);return result;}
}

1.5、启动测试

http://localhost/consumer/payment/hystrix/ok/10

高并发压测提供者8001延时三秒服务,20000次,再执行下面的请求

再通过80远程调用访问查看ok接口和自身自测正常的ok接口

消费者80服务:要么转圈圈,要么出现超时现象

4.3、故障现象和导致原因

正因为有上述故障或不佳表现才有我们的降级/容错/限流等技术诞生

解决方案

  1. 超时导致服务器变慢(转圈):超时不再等待
  2. 出错(宕机或程序运行出错):出错要有兜底
  3. 对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
  4. 对方服务(8001)宕机了,调用者(80)不能一直卡死等待,必须有服务降级
  5. 对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级

Hystrix断路器入门1相关推荐

  1. SpringClound——Hystrix断路器

    SpringCloud学习资料汇总超级棒的 如上是我在看文章时忽然看到的一个很好的学习SpringCloud的网站 SpringClound--微服务概述--史上最烂 SpringClound--Sp ...

  2. Spring Cloud构建微服务架构:服务容错保护(Hystrix断路器)【Dalston版】

    前言 在前两篇<Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)>和<Spring Cloud构建微服务架构:服务容错保护(Hystrix依赖隔离)&g ...

  3. Hystrix面试 - 深入 Hystrix 断路器执行原理

    Hystrix面试 - 深入 Hystrix 断路器执行原理 RequestVolumeThreshold HystrixCommandProperties.Setter().withCircuitB ...

  4. SpringCloud中 Feign结合Hystrix断路器开发。

    Feign结合Hystrix断路器开发: 转载于:https://www.cnblogs.com/longdb/p/10468371.html

  5. Hystrix断路器执行原理

    深入 Hystrix 断路器执行原理 Hystrix熔断机制,用于监控微服务调用情况,当失败的情况达到预定的阈值(5秒失败20次),会打开断路器,拒绝所有请求,直到服务恢复正常为止. circuitB ...

  6. 五、Hystrix断路器

    Hystrix断路器 概述 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每一个依赖关系在某些时候将不可避免的失败. 服务雪崩 多个微服务之间调用的时候,假如微服务A调用微服务 ...

  7. Hystrix断路器原理及实现(服务降级、熔断、限流)

    Hystrix断路器原理及实现(服务降级.熔断.限流) 分布式系统面临的问题 Hystrix重要概念(面试常考) Hystrix案例 Hystrix 服务提供者 Hystrix 服务消费者 原因与解决 ...

  8. Netflix Hystrix断路器简介与工作原理

    一.前言? 1.Netflix Hystrix断路器是什么? Netflix Hystrix是SOA/微服务架构中提供服务隔离.熔断.降级机制的工具/框架.Netflix Hystrix是断路器的一种 ...

  9. 微服务——Hystrix断路器(豪猪哥)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 概述 分布式系统面临的问题 是什么 能干嘛 Hystrix重要概念 服务降级(fallback) 哪些情况会触发降级 服务熔 ...

最新文章

  1. 自监督学习,如何从数据困境中拯救深度学习?
  2. matlab 用fplot和plot作出函数图像
  3. MATLAB与Python numpy矩阵操作对应表
  4. python的turtle画曲线_python的turtle模块画折线图
  5. Spring Boot入门——JPA
  6. 配置解决中文乱码的过滤器
  7. python tablewidget 颜色_QT中,QTableView鼠标移动到item上时该item所在行的背景颜色变成其他颜色,这要怎么实现...
  8. c/c++,字符,字符串,各种方式读入与对空格,回车的处理
  9. [JavaScript] 使用ArrayBuffer和Blob编辑二进制流 下载文件
  10. html5怎么给图片添加背景透明,javascript – 透明图像背景html5画布
  11. 思科 GNS3 配置 NAT 端口映射
  12. Android Studio IDE Out of Memory
  13. 这5小段代码轻松实现数据可视化(Python+Matplotlib)
  14. xdebug常用配置
  15. 个人博客 修改markdown代码块背景颜色
  16. 调研之路 --- MXF
  17. java PDF模板生成并导出(文字、表格、图片)
  18. 一个新手的评价---人机交互方面(有些不搭题
  19. eclipse的32位和64位版本(亲测有效)
  20. 输入一个长度不超过100的字符串,删除串中的重复字符。

热门文章

  1. llvm -DLLVM_TARGETS_TO_BUILD
  2. 什么是撞库及撞库攻击的基本原理
  3. MAC执行sed命令报“command c expects \ followed by text”错误解决办法
  4. 推荐:做人的基本原则 - 温
  5. 从输入url到页面展示出来经历了哪些过程
  6. ImageNet数据下载
  7. vjudge——HDU刷题顺序
  8. Neo4j 自定义函数
  9. 中国牙齿修复材料行业市场供需与战略研究报告
  10. 新势力 | 赛宁工控安全产品体系——护航工业网络安全