
在微服务架构中,一个请求需要调用多个服务是非常常见的。**但!!**
如客户端访问A服务,而A服务需要调用B 服务,B服务需要调用C服务
但!!

B服务或者C服务不能及时响应
A服 务将处于阻塞状态,直到B服务C服务响应。导致服务瘫痪。会对整个微服务系统造成灾难性的严重后果 这就是服务故障的“雪崩”效应。雪崩的根本原因来源于服务之间的强依赖**
所以我们可以提前评估,做好:**熔断**,**隔离**,**限流。** 避免雪崩的产生~各个模块之间相对独立,无强依赖。**能将问题和影响隔离在某个模块内部
而不扩散风险,不波及其它模块,不影响整体的系统服务。电压高~保险丝断~跳闸~保护电器
在互联网系统中,当下游服务因访问压力过大而响应变慢或失败
上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。直接返回错误,或者降级处理。**
所谓降级,就是当某个服务熔断之后,服务器将不再被调用
此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值.也可以理解为 兜底
fallback回调方法是对你目前请求失效后的一个解决方案:hystrix** 很好的实现了熔断和降级的功能。
他的主要思想是,设置一些阀值,比如,最大并发数,错误率百分比,熔断尝试恢复时间等。
通过这些阀值来转换熔断器的状态:
1.关闭状态,允许调用依赖
2.打开状态,不允许调用依赖,直接返回错误,或者调用fallback
3.半开状态,根据熔断尝试恢复时间来开启,允许调用依赖,如果调用成功则关闭失败则继续打开
一旦检测达到的限制的阈值,就限制流量访问并采取少量措施以完成限制流量的目的。比如,我们限制每秒最大处理200个请求,超过个数量直接拒绝请求。logo:**非洲的一个动物, 豪猪~我也不知道为啥..就很nice~**
Netflflix开源的**一个**延迟和容错库**用于隔离访问远程系统、服务或者第三方库,防止级联失败: 从而提升系统的可用性与容错性。
被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也是很正常的。容错机制.**这种故障在整个系统所有的依赖服务调用中进行蔓延时
Hystrix还提供故障时的fallback降级机制总而言之,Hystrix通过这些方法帮助我们提升分布式系统的可用性和稳定性延迟 容错HystrixCommand包裹** 对依赖的调用逻辑包裹,**使每个命令在独立线程中执行。
一般来说是对于经常使用的方法进行包裹~ 不是很长调用的并不需要进行包裹~**
也对 Hystrix 也主要是做熔断的…**防止雪崩**对于不经常使用的方法也不会**崩坏**包裹 服务的错误率超过一定的阈值时,自动**或**手动跳闸**,停止请求:服务一段时间
错误率:当请求满足一定的数量默认20 且请求失败比例的大于 50% Hystrix就会使服务暂时的停止...
使服务冷静一段时间, 这段时间都是响应一个可正常运行的fallback方法, 并不会让你的程序卡在这儿…
等过一段时间, 又会自动的又将 服务打开~让你进行访问… 整个过程都是自动的!发往该依赖的请求就被立即拒绝,而不是排队等待,从而加速失败判定。(也是保护服务正常运行的一种形式...)
下面的 Hystrix监控就是靠着这些线程需要进行的操作..例如成功、失败、超时、以及被拒绝的请求等。断路器打开一段时间后,会自动进入“半开”状态。
半开状态: 有可能之后变为打开, 有可能是关闭状态; 半开状态对当前情况一种分析,来觉得之后的状态情况!实战!ok, 终于经过了上面 乱七八糟,令人头疼的理论终于到了代码了…
什么是雪崩 熔断 降级 …处理雪崩的 熔断降级
rest 是调用方请求的一种方式…Hystrix 一般对调用方的方法进行 包裹监视 如果出现问题进行降级 fallback**处理**在之前项目基础上更改: 不了解同学可以点击这儿!!**耐心学习~**

严格遵循了SpringCloud的 三板斧原则:依赖 配置 注解
pom.xmlpom.xml
<!-- hystrix实现服务熔断 -->
<!-- 熔断器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringCloud 对hystrix 的starter全部依赖集成... -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>.yml.yml
#不在任何节点写属性,它就是首级...
management:
endpoints:
web:
exposure:
include: hystrix.stream # hystri流文件实时监控的文件
#stream流: 配置这个表示状态信息已流的方式 实时进行记录;包裹方法的执行状态!
http://localhost:对应调用者端口/actuator/hystrix.stream
本人这里都是已学习为主的,所以都是localhost本地的ip
主程序类, 几乎不要任何的配置!就只要一个注解:
表示, 开启Hystrix的熔断降级!接下来介绍 熔断降级的两种实现~ controller层进行的修改! 在最顶上进行的**降级!**
服务降级 @HystrixCommand包裹的controller请求方法上!**fallbackMethod = "指定的降级方法" 并通过 fallbackMethod 属性指定一个降级方法
当原方法出现异常, 则会直接执行 降级方法.一模一样的方法!!**
参数 参数类型 返回值 …修饰符! ~类型真的坑我就写错成 int 和 Integer找了半天的错~UserController.Java
//编程控制层,接受请求响应结果
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/showUserOrder") //页面请求的方法名,get方式请求!
@HystrixCommand(fallbackMethod = "showUserOrderFallBack") //给方法指定一个局部熔断方法;
public List<Order> showUserOrder(Integer uid){
int num = (int) (Math.random() * 10); //这里为了方便看到效果,本人决定手动随机抛出异常! 70%几率
System.out.println(num);
if (num > 7) {
throw new RuntimeException(); //主动对外抛出异常...
}
return userService.currentUserOrder(uid);
//Service又是通过网络调用 订单模块来响应的结果,因此在此基础上要缺点订单模块是运行中的...
}
//局部熔断器方法...方法名外: 一模一样
public List<Order> showUserOrderFallBack(Integer uid){
//这里主要做的就是对请求的一种处理,方法: 假的数据....
System.out.println("局部熔断方法");
List<Order> list = new ArrayList<>();
list.add(new Order(0, "进入熔断降级方法", 0.0, uid));
return list;
}
}
服务降级 @DefaultPropertiesdefaultFallback = "全局的降级方法"** 指定全局的**降级处理** 类中任一个报错都会进入该方法实现的降级方法** 不在需要一模一样…因为你也不知道要啥参数 返回值了…
需要注意: 虽然@DefaultProperties在类上声明了
还是要给 要降级的方法上声明 @HystrixCommand但是不用在指定降级方法了!!UserController.Java
//编程控制层,接受请求响应结果
@RestController
@DefaultProperties(defaultFallback = "commonFallBack") //全局熔断器 (如有控制器抛出异常直接进到这个方法)
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/showUserOrder") //页面请求的方法名,get方式请求!
@HystrixCommand//(fallbackMethod = "showUserOrderFallBack") //给方法指定一个局部熔断方法;
public List<Order> showUserOrder(Integer uid){
int num = (int) (Math.random() * 10); //这里为了方便看到效果,本人决定手动随机抛出异常! 70%几率
System.out.println(num);
if (num > 7) {
throw new RuntimeException(); //主动对外抛出异常...
}
return userService.currentUserOrder(uid);
}
// //局部熔断器方法...方法名外: 一模一样
// public List<Order> showUserOrderFallBack(Integer uid){
// //这里主要做的就是对请求的一种处理,方法: 假的数据....
// System.out.println("局部熔断方法");
// List<Order> list = new ArrayList<>();
// list.add(new Order(0, "进入熔断降级方法", 0.0, uid));
// return list;
// }
//全局熔断器方法... 因为是全局的所以参数就不好提供了;
public List<Order> commonFallBack(){
System.out.println("全局熔断方法");
List<Order> list = new ArrayList<>();
list.add(new Order(0, "全局熔断方法", 0.0, 1));
return list;
}
}
异常处理的**, 不一定在调用方写的!pom.xml 导入对应依赖.yml 配置@EnableCircuitBreakerHystrix 对降级操作提供一个监控器平台
主要作用是:
.yml 配置的监控文件, 它可以对文件进行监视.实时的数据**!!
毕竟 没人喜欢一直盯着这个满屏的子 瞅! 😥
hystrix-dashBoard-server
这个监控平台实现的话,特别容易! 就 依赖 配置监控平台端口 启动主程序即可!!
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>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hystrix-dashBoard-server</artifactId>
<dependencies>
<!-- hystrix实现服务熔断 -->
<!-- 熔断器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringCloud 对hystrix 的starter全部依赖集成... -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 仪表盘:等会页面展示需要的依赖: -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
</dependencies>
</project>.ymlapplication.yml
server:
port: 7003本人的端口 7003~**这个随便搞都行!**
@EnableHystrixDashboardMyHystrixDashBoardServer.Java
@SpringBootApplication
@EnableHystrixDashboard
public class MyHystrixDashBoardServer {
public static void main(String[] args) {
SpringApplication.run(MyHystrixDashBoardServer.class, args);
}
}正常不能在正常的SpringBoot 微服务项目, 就加了一个注解 @EnableHystrixDashboard
启动数据图形化仪表盘
localhost:服务端口/hystrix这样就表示成功了!!


再次强调指定要查看的 监视流文件(copy): http://localhost:被监控的端口/actuator/hystrix.stream
ok, 进入监控文件!


需要注意这里**端口状态**:
CLOSED,当触发熔断后状态变更为OPEN
在等待到指定的时间,Hystrix会放请求检测服务是否开启,这期间熔断器会变为 HALF_OPEN
半启状态,熔断探测服务可用则继续变更为 CLOSED 关闭熔断器。失败次数超过了在给定时间内允许失败的阈值,则代理类切换到断开(Open)状态。
此时代理开启了一个超时时钟,当该时钟超过了该时间,则切换到半断开(Half-Open)状态。
该超时时间的设定是给了系统一次机会来修正导致调用失败的错误。默认20次 失败率 50%以上(默认是5S)。**
随后断路 器会自动进入半开状态。此时会释放1次请求通过,若这个请求是健康的,则会关闭断路器
否则 继续保持打开,再次进行5秒休眠计时.
上面已经通过 Hystrix 实现了,
监视器实时的监控数据, 但只是对于一个请求的使用, 那么如果有很多呢?
我怎么一下子看很多, 开很多的 Hystrix监视页面吗? 一个页面一个? 很显然是不行滴!!

因为要给监控器加一个 监视多个的操作,这是要修改 监控平台的
依旧**三板斧**坚持到底~~
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>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hystrix-dashBoard-server</artifactId>
<dependencies>
<!-- hystrix实现服务熔断 -->
<!-- 熔断器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- SpringCloud 对hystrix 的starter全部依赖集成... -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- 仪表盘:等会页面展示需要的依赖: -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!-- 导入turbine所需要的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
</dependencies>
</project>.yml 文件application.yml
server:
port: 7003
spring:
application:
name: my-cloud-hystrix-dashboard
#注册至eureka上
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
prefer-ip-address: true
turbine:
# 要监控的微服务列表,多个用,分隔
app-config: user-server
cluster-name-expression: "'default'"
#因为归根结底,想要通过turbine来实现多服务监控;
#底层是将多个服务模块的流文件写入到一个 turbine的流文件;
#htstrix监视器解析的是 汇总之后的turbine的流文件————实现多文件查看!!加了一个 注册中心 因为它要去注册中心上去找, 要监控对应的服务…
注册中心可以提供方便的访问!!
turbine配置
turbine的流文件;MyHystrixDashBoardServer.Java
@SpringBootApplication
@EnableHystrixDashboard //作为一个独立的监控项目,需要配置启动类,开启HystrixDashboard监控平台
@EnableTurbine //并激活Turbine
public class MyHystrixDashBoardServer {
public static void main(String[] args) {
SpringApplication.run(MyHystrixDashBoardServer.class, args);
}
}首先Eureka**注册中心**上可以看到 已经都在注册中心上了: 可以实现访问了

分布直接查看**实时监控文件的情况**可以看到页面是在不停的**实时刷新,监测新的数据~**
单文件 http://localhost:6002/actuator/hystrix.stream
汇总文件 http://localhost:7003/turbine.stream
前面端口别在意, 根据自己情况来! 后面的请求路径才是要注意 需要copy的!
查看多文件监视的时候,**使用汇总文件~**

三板斧!!
提供注册中心配置,为了更好的去汇总模块的监视文件 Turbine根据 , 逗号分隔添加多个要汇总的模块..激活Turbine默认已为Feign整合了hystrix**不用在添加hystrix依赖**可以参考这里:拉到最后Fegin**服务调用**

和之前相比加了一个 Fegin服务调用的接口实现, 专门为其做熔断的类 OrderFeginRD
不需要加入什么依赖**pom.xml
#fegin 就是最顶层!
feign:
hystrix:
enabled: true #开启fegin的熔断FeginRD 熔断包;定一个一个实现类
实现Fegin服务调用的 提供者provide模块,接口
OrderFeginRD.Java
//把普通pojo实例化到spring容器中,相当于配置文件中的 )
@Component
public class OrderFeginRD implements OrderFeginClient {
@Override
public List<Order> findOrderByUser(Integer uid){
//这里做的就是熔断服务降级的,处理方法...根据需求来呗! 本人就返回一个 List:Order Fegin熔断!
System.out.println("Fegin熔断降级!!");
List<Order> list = new ArrayList<>();
list.add(new Order(1, "Fegin的熔断方法", 0.0, 1));
return list;
}
}它主要是实现采用 Fegin调用模块, 所引入调用模块 声明的接口
OrderFeginClient.Java
//@FeignClient指定需要调用的微服务名称
@FeignClient(value = "order-server",fallback = OrderFeginRD.class)
public interface OrderFeginClient {
//调用的请求路径,要注意这里尽量要和 提供者的实现方法一模一样包括参数,参数类型!!
@GetMapping("/findOrderByUser/{uid}")
public List<Order> findOrderByUser(@PathVariable("uid") Integer uid);
}fallback = OrderFeginRD.class 指定当改接口实现, 出现错误进行熔断降级的实现类 OrderFeginRD
@EnableFeignClients这个应该不会忘, 毕竟Fegin的服务调用,也需要这个注解来实现:**@EnableFeignClients 启动Fegin的支持!**
因为Fegin的内部实现了 hystrix 所以不需要在引入什么依赖~一模一样的接口方法!Fegin的底层对其做了实现!给Service直接调用!重写的方法就是后面熔断降级方法 Fallback@FeignClient(value = "order-server",fallback = OrderFeginRD.class)
value = “order-server” 引入要调用的模块名~
fallback = “当方法异常,熔断降级的类!” 目前这个降级类就是 当然接口的实现类!因此:Fegin的熔断策略是针对 , 调用方的调用方出现异常, 则执行Fallback的降级方法~ok, 这就实现了Fegin的熔断, 是不是特别简单!!
说实话把, 难? 不难但是SpringCloud / Boot 的东西:注解/中间件/依赖…
实在太多了!不费点劲, 可不容易完全搞懂!
Sentinel短期内**,Hystrix依然是继续使用的。Alibaba Sentinel
阿里巴巴开源**的一款断路器实现
目前在Spring Cloud的孵化器项目Spring Cloud Alibaba中的一员
Sentinel本身在阿里内部已经被大规模采用,非常稳定。因此可以作为一个较好的替代品。
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。
Sentinel 以流量为切入点: 从流量控 制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入您可以通过实现扩展接口来快 速地定制逻辑。例如定制规则管理、适配动态数据源等
这里使用的是 用户模块common_userService:**已经采用hystrix 实现了熔断!就不在用Sentinel 处理熔断降级了**
熔断降级~ 只是使项目被管理 监控! 所以代码不多就导了个 依赖pom 配置.yml!
使用前要确保存在,启动一个:**管理控制台**
您可以从官方网站中下载最新版本的控制台 jar 包 sentinel-dashboard-1.6.3.jar
在Jar包路径下执行,使用如下命令**启动控制台:**
java -Dserver.port=10000 -Dcsp.sentinel.dashboard.server=localhost:10000 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.6.3.jar上述的两个 10000 更改为你要修改的端口号:xxxsentinel

给要进行管理的 项目模块导入Sentinel的依赖:**pom.xml**
<!-- 阿里巴巴 Sentinel所需依赖: -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>引入父工程依赖:**pom.xml**
<!-- <dependencyManagement></> :结构下,因为是阿里巴巴的依赖,需要引入阿里巴巴的 父依赖! -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>1.5.0.RELEASE</version>
<type>pom</type> <!-- 因为这里是 pom所以是父工程的 -->
<scope>import</scope>
</dependency>application.yml
spring:
application:
name: user-server #服务模块名!
cloud:
sentinel:
transport:
dashboard: http://localhost:1000 #这里设置需要引入,你Sentinel 的路径!
在目录下通过命令启动服务被平台管理!