热部署对于Hystrix的热不是不是很明显 所以最好修改代码之后重启服务
简介
在微服务架构中存在多个可直接调用的服务,这些服务若在调用时出现故障会导致连锁效应,也就是可能让整个系统变得不可用,这种情况我们称之为服务雪崩效应.
服务雪崩效应通常发生在微服务架构中,当一个服务发生故障时,由于服务间的依赖关系,这个故障可能会导致依赖它的其他服务也跟着出现问题,从而形成连锁反应。例如,如果一个用户认证服务突然宕机,所有依赖这个认证服务来验证用户身份的服务都无法正常工作,最终导致整个系统变得不可用。这就好比一张网,当网中的一个节点被割断时,与这个节点直接连接的其他节点也会受到影响,进而可能影响整个网的稳定性。
Hystrix是一个用于处理分布式系统的延迟和容错的库,旨在隔离访问远程服务、第三方库,防止级联失败,提供回退机制以及近实时的监控。它能保护系统在某个服务失败时不会导致整个系统的瘫痪,通过断路器模式来实现。当某个服务的失败率超过一定阈值时,Hystrix会自动切断调用,防止这个故障扩散到其他服务。除Hystrix外,相似功能的有Resilience4j、Sentinel等。Hystrix目前已进入维护模式,Netflix推荐使用Resilience4j作为替代。
“维护模式”意味着Hystrix已经停止了主动开发,不再添加新功能。它只接受必要的安全更新或错误修复。这种状态通常会导致推荐使用新的、活跃开发的替代品用于生产环境。
总体而言:为了避免级联故障蔓延,导致服务雪崩,一种提高分布式弹性的,高可用自救措施
作用:1.服务降级 2服务熔断 3接近实时的监控.
服务降级 fallback 对方系统不可用了,你需要给我一个兜底的解决办法
哪些情况会发出降级:
1.程序运行异常
2.超时
3.服务熔断触发服务降级
4.线程池/信号量打满也会导致服务降级
服务熔断(服务降级的升级版本哈哈哈) break 好比保险丝,达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法再返回友好提示兜底
服务限流 flowlimit 秒杀高并发等操作,严禁一窝蜂的拥挤,大家排队,一秒钟N个,有序进行
看样子都是自救措施 需要采取诸如服务降级、熔断、限流等自救措施来防止雪崩效应的发生。
https://github.com/Netflix/Hystrix/wikihttps://github.com/Netflix/Hystrix/wiki
构建Cloud
父项目只做依赖版本管理,不引入依赖
pom.xml
<!-- 统一管理jar包版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
</properties>
<!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>cloud</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.2.RELEASE</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
构建生产者模块
pom.xml
hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zookeeper-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.yml
server:
port: 8081
spring:
application:
name: cloud-provider-hystrix-payment
cloud:
zookeeper:
connect-string: 222.22.22.22:2181
业务类
启动类
测试
localhost:8081/pay/hystrix/ok/1
下面稍微慢点
两个接口都OK
IP:8888//commands/stat
用JMeter压测
Apache JMeter - Apache JMeter™https://jmeter.apache.org/
解压之后 bin
不知为何重影很卡 下面有解决方式
可以看到 当大规模并发打进来的时候
后端出现明显卡顿
JMeter重影问题
在高分辨率显示器上使用 JMeter 时出现重影或界面显示不清晰的问题,通常是由于 Java 应用程序在高 DPI 设置下的缩放问题导致的。这个问题比较常见于4K或更高分辨率的显示器,尤其是在Windows系统上。以下是一些可能帮助解决这个问题的解决方案:
在bin目录下创建 setenv.bat文件
编辑
@echo off
rem Set custom JVM arguments for JMeter
rem Disable DirectDraw to potentially fix high DPI rendering issues
set JVM_ARGS=-Dsun.java2d.noddraw=true
rem Optionally, you can add more JVM arguments here
rem For example, to disable DirectDraw offscreen surfaces acceleration
rem set JVM_ARGS=%JVM_ARGS% -Dsun.java2d.ddoffscreen=false
rem To enable hardware-accelerated scaling
rem set JVM_ARGS=%JVM_ARGS% -Dsun.java2d.ddscale=true
rem Set the maximum heap size and other memory settings if needed
rem set JVM_ARGS=%JVM_ARGS% -Xmx1g -Xms256m
构建消费者模块
pom.xml openfeign带有Ribbon依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zookeeper-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
启动类 因要使用openfeign
添加@EnableFeignClients
业务类
application.yml
server:
port: 80
spring:
application:
name: cloud-consumer-hystrix-order
cloud:
zookeeper:
connect-string: 222.2222.222.22:2181
ribbon:
#指定建立连接所用时间
ReadTimeout: 8000
#读取可用资源时间
ConnectTimeout: 8000
如果此时用JMeter对8081测压 那么80生产者这边肯定也会出现卡顿或者报错现象
我设置了消费者的调用限时8秒 生产者那边超时时间我设置了15秒 必定报错 但是报错体验更定不好 来个兜底方法
生产者模块改造
注意 我们设置了消费者调用时间是 8秒
也是可以使用的
那么以上是在生产者做服务降低处理的保护
消费者端也可以做服务降低保护处理
application.yml
客户端启动类
生产者这边 我将服务降级代码 注释掉
全局服务降级
每个业务方法对应一个兜底方法,代码混乱,应该统一和自定义分开
Global fallback
另外一种
可以在openfeign调用的接口去定义
在生产者 我故意让代码报错
消费者
控制器
openfeign调用接口
实现类
概述
以上就是服务降级 程序运行异常,超时,服务熔断触发服务降级,线程池/信号量打满也会导致服务降级
服务熔断
熔断机制是应对服务雪崩效应的一种微服务链路保护机制,当某个微服务出错不可用或响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用
当检测到该节点微服务调用响应正常之后,恢复调用的链路
Hystrix可以实现SpringCloud中的熔断机制.当失败的调用达到一定阈值,默认是5秒内20次调用失败,就会启动熔断机制.熔断机制的注解是@HystrixCommand.
服务熔断的过程:服务降级->进而熔断->恢复链路
在生产者业务层 意思id正数 正常 id负数 就进入服务降级的方法
//服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"), //是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), //时间范围
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"), //失败率达到多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id){
if (id < 0){
throw new RuntimeException("*****id 不能负数");
}
String serialNumber = UUID.randomUUID().toString().replace("-", "");
return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
return "id 不能负数,请稍候再试,(┬_┬)/~~ id: " +id;
}
生产者Controller
如果我现在调用 负数 达到峰值 多次调用之后 即使我输入的数是正确的 还是到了错误的方式
这个就是服务熔断 然后慢慢恢复
限流 不会
服务监控HystrixDashboard
仪表盘,图形化监控
application.yml
pom.xml
<dependencies>
<!--新增hystrix dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</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>
在生产者配置
@Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; }
localhost:9001/hystrix
访问生产者接口
我这边都没引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>