05-互联网架构服务降级熔断Hystrix
05-互联网架构服务降级熔断Hystrix
互联网架构服务降级熔断Hystrix
一. 分布式核心知识之熔断,降级讲解
系统负载过高,突发流量或者网络等各种异常情况介绍,常用的解决方案
1. 熔断
保险丝,熔断服务,为了防止整个系统故障,包含自己和下游服务
下单服务 -> 商品服务
-> 用户服务(出现故障 -> 熔断)
2. 降级
抛弃一些非核心的接口和数据
只带核心的物品,抛弃非核心的,等有条件时再恢复
3. 熔断和降级互相交集
-
相同点
1)从可用性和可靠性出发,为了防止系统崩溃
2)最终让用户体验到的是某些功能暂时不能用 -
不同点
1)服务熔断一般是由下游服务故障导致的,而服务降级一般是从整体系统负荷考虑,由调用方控制
二. Netflix开源组件断路器Hystrix介绍
1. 什么是Hystrix
hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与hystrix本身的功能不谋而合,因此Netflix团队将该框架命名为Hystrix,并使用了对应的卡通形象做作为logo。
2. 为什么要用
在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。
3. 熔断之后如何处理
出现错误之后可以fallback 错误的处理信息
兜底数据
三. Feign结合Hystrix断路器开发实战
1. Hystrix单独使用
-
导入maven依赖
org.springframework.cloud spring-cloud-starter-netflix-hystrix
这个依赖主要是为了使用@HystrixCommand(fallbackMethod = "saveOrderFail")
-
启动类添加注解
@EnableCircuitBreaker
-
添加Hystrix命令注解
@HystrixCommand(fallbackMethod = "saveOrderFail")
-
编写兜底数据方法(即熔断之后的错误处理信息)
public Object saveOrderFail(Integer userId, Integer productId){
Map<String, Object> msg = new HashMap<>();
msg.put("code", -1);
msg.put("msg", "抢购人数太多,您被挤出来了,稍等重试");
return msg;
}
注意: 方法签名(方法名和参数列表)必须和原方法一样
2. Feign结合Hystrix使用
feign本身已经集成了Hystrix组件,但是默认关闭,需要先打开
-
配置feign的Hystrix组件
feign:
hystrix:
enabled: true
-
创建实现了加了@FeignClient注解的接口的实现类
Fallback class for the specified Feign client interface. The fallback class must implement the interface annotated by this annotation and be a valid spring bean.
@Component
public class ProductClientFallback implements ProductClient {
@Override
public String findById(Integer id) {
System.out.println("findById fallback异常");
return null;
}
} -
在@FeignClient上加上该类配置
@FeignClient(name = "product-service", fallback = ProductClientFallback.class)
这样就完成了对于Client接口内方法的fallback兜底数据,相当于对异常的处理,只不过是比较高级的熔断
四. 熔断降级服务异常报警通知实战
1. redis简介
2. 步骤
-
安装redis
解压以后,进入redis目录,输入指令redis-server.exe redis.windows.conf即可启动redis服务器
设置redis密码等 -
导入springboot-redis依赖
org.springframework.boot spring-boot-starter-data-redis -
配置文件中配置redis
spring:
redis:
database: 0
host: 127.0.0.1
port: 6379
timeout: 2000 -
在fallback中编写利用redis缓存报警机制
String orderFunName = "save-order";
String orderMessage = redisTemplate.opsForValue().get(orderFunName);
String ip = request.getRemoteAddr();
new Thread( ()-> {
if(StringUtils.isBlank(orderMessage)){
System.out.println("紧急短信,用户下单失败,ip为 " + ip);
redisTemplate.opsForValue().set("save-order", "save-order-fail", 20, TimeUnit.SECONDS);
}else{
System.out.println("已发送短信,20S内不重复发送");
}
}).start();
注: 以后这里使用发送短信提醒
3. 常见问题
-
TimeoutException
设置熔断器检测时间(默认1秒)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000关闭熔断器超时检测时间功能,也就是不超时
hystrix.command.default.execution.timeout.enabled: false直接禁用feign的hystrix
feign.hystrix.enabled: false -
NOAUTH Authentication required
配置redis密码,重启redis服务器
五. Hystrix降级策略和调整
官方文档 https://github.com/Netflix/Hystrix/wiki/Configuration#execution.isolation.strategy
1. Hystrix降级策略
execution.isolation.strategy 隔离策略
THREAD 线程池隔离 (默认)
每个服务分配固定的线程池数量,即使挂掉也不会造成整个服务的堵塞
SEMAPHORE 信号量
信号量适用于接口并发量高的情况,如每秒数千次调用的情况,导致的线程开销过高,通常只适用于非网络调用,执行速度快
设置一个计数器,超过一定的数量后新连接不可访问
2. 超时时间管理
execution.isolation.thread.timeoutInMilliseconds 超时时间
默认 1000毫秒
execution.timeout.enabled 是否开启超时限制 (一定不要禁用)
execution.isolation.semaphore.maxConcurrentRequests 隔离策略为 信号量的时候,如果达到最大并发数时,后续请求会被拒绝,默认是10
3. 超时时间调整
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
六. 断路器Dashboard监控仪表盘
1. 加入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. 启动类加入注解
@EnableHystrixDashboard
3. 配置文件增加endpoint
management:
endpoints:
web:
exposure:
include: "*"
4. 访问入口
http://localhost:8781/hystrix
Hystrix Dashboard输入: http://localhost:8781/actuator/hystrix.stream
参考资料
默认开启监控配置
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-security-actuator
配置文件类:
spring-configuration-metadata.json