SpringCloud Netflix Hystrix
容错
在一个分布式系统里,一个服务往往要调用多个服务,可能存在某个服务调用失败, 比如超时、异常等,
要使用容错框架保证在某些服务调用出问题时,不会拖垮整个调用链路,系统依然可用。
Hystrix
Hystrix是一个容错框架,提供了隔离、熔断、服务降级、监控、cache等功能,可以有效防止被调服务故障造成的级联故障。
和eureka、ribbon、feign一样,hystrix也是Netflix旗下的项目,都被SpringCloud集成了。
服务限流
当此消费者对某提供者请求个数较多时,消费者可以限制自身对提供者发起的请求个数,请求个数超过指定的值时,使请求快速失败。
Hystrix的限流方式有2种:线程池、信号量。
服务监控
监控请求的失败率(一定时间内,请求失败个数)达到阈值,就打开断路器,熔断链路,使后续的请求快速失败。
熔断
熔断服务,包含被调用者、链路的下游服务,防止下游服务的故障影响到上游服务。
服务降级
服务调用失败默认会返回一堆英文的错误信息给用户,很不友好。
服务降级是在服务调用失败时自动执行预案,预案使用相同参数表、返回值类型,是备胎、次选,
预案可以只保留核心业务、抛弃不重要的业务,比如电商网站qps很大时,用户查询商品信息这一操作,标准业务是获取商品信息+评论+相似商品(商品推荐),预案只保留查询商品信息这一核心业务,去掉获取评论、推荐商品等非核心业务。
预案也可以连核心业务都不要,直接给出“太挤了,请稍后重试”之类的友好提示。
熔断和降级的异同点
相同点:从可用性和可靠性触发,防止系统崩溃,某些功能暂时不可用
不同点:服务熔断一般是下游服务故障导致的,而服务降级一般是从服务负载考虑,由调用方控制
自我修复
自我修复其实就是断路器状态的切换,断路器打开(熔断)后5min内的请求都快速失败;5min后断路器半开,放行部分请求,
如果这些请求(服务调用)都成功了,说明问题已修复,关闭断路器,链路恢复通行;否则继续下一个5min。
5min是窗口期,数值可以调。
使用Hystrix
Hystrix是在消费者(调用方)中使用的,一般要和Feign搭配使用
(1)在创建消费者时勾选Spring Cloud Circuit Breaker -> Hystrix [Maintenance]
也可以手动加hystrix的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
(2)引导类上加 @EnableCircuitBreaker或@EnableHystrix
@EnableHystrix中包含了@EnableCircuitBreaker这个注解
(3)在controller中设置回退方法
@Controller
@RequestMapping("/api/v1/user")
public class UserController {
@Resource
// private RestTemplate restTemplate;
private OrderFeignService orderFeignService; @RequestMapping("order/{user_id}")
@ResponseBody
@HystrixCommand(fallbackMethod = "findOrdersByUserIdFail") //指定回退方法
public Map<String,Object> findOrdersByUserId(@PathVariable("user_id") Integer userId){
//调用服务
// List<Order> orders = restTemplate.getForObject("http://order-service/api/v1/order/list/" + userId, List.class);
List<Order> orders = orderFeignService.findOrdersByUserId(userId); HashMap<String, Object> map = new HashMap<>();
map.put("code", 0);
map.put("data", orders); return map;
} /**
* 回退方法,回退方法命名一般是原方法名+Fail
*/
public Map<String,Object> findOrdersByUserIdFail(Integer userId){
//参数:远程服务接口,返回值类型(目标类型)
HashMap<String, Object> map = new HashMap<>();
map.put("code", -1);
map.put("msg", "人太多了,你被挤出来了,请稍后重试");
return map;
} }
Hystrix一般是在controller中设置的,也可以在其它地方进行设置。但服务调用要写在service层、然后在controller中调用service层,我这里图方便直接在controller中调用服务。
使用Feign、RestTemplate调用服务都可以。
返回的时候一般用map装载数据,code表示处理情况,前端或上游服务根据码值确定处理的情况,进行对应的数据展示。
比如code=xx表示处理成功了,如果是数据查询,用表格还是什么把获取的数据展示出来;如果code=xx表示处理失败,用提示框告诉用户失败了。
当然回退方法可以直接返回null,如果返回null,前端、上游服务处理返回结果时需要先判断返回的数据是否为null。
@HystrixCommand(fallbackMethod = "findOrdersByUserIdFail")标注在某个方法上,只对该方法有效;
@DefaultProperties(defaultFallback = "findOrdersByUserIdFail")标注在类上,对类中所有的方法都有效,该类中的某个方法执行失败时,都会调用默认的回退方法来代替。
使用Feign自带的Hystrix
上面的方式使用的是单独的Hystrix,也可以使用Feign内置的Hystrix。
同样是在消费中使用的,创建消费者时不需要勾选Hystrix,不需要添加Hystrix的依赖,因为Feign的依赖中已经包含了Hystrix。
在引导类中不需要使用Hystrix的注解
@EnableFeignClients
// @EnableHystrix
// 或者@EnableCircuitBreaker
(1)在配置文件中开启feign自带的hystrix
feign:
hystrix:
enabled: true
默认是false,需要手动开启
(2)写一个类实现Feign接口,和Feign接口放在同一个包下
@Component //放到spring容器中
public class OrderFeignServiceFallback implements OrderFeignService { //实现的方法就是接口中对应方法的回退方法
@Override
public List<Order> findOrdersByUserId(Integer user_id) {
return null;
} }
(3)在Feign接口中指定对应的回退类
@FeignClient(name = "order-service", fallback = OrderFeignServiceFallback.class)
public interface OrderFeignService { @GetMapping("/api/v1/order/list")
List<Order> findOrdersByUserId(@RequestHeader("user_id") Integer user_id); }
使用时不需要使用 @HystrixCommand 指定回退方法,调用失败时会自动执行回退类中对应的回退方法。
2种方式的比较
- 作用范围
第一种在哪里使用都行,可以给controller、service、dao或者其他地方的方法指定回退方法,哪个方法都可以加回退方法;
第二种只是给服务调用加回退方法,只作用于服务调用的语句。
- 服务调用方式
第一种可以使用RestTemplate或者Feign,第二种只能使用Feign。
总之第二种的使用范围很有限,只能对Feign方式的服务调用起到容错保护;
第一种的使用范围十分广泛,不局限于服务调用,可对整个应用起到容错保护,功能更加强大。
报警通知
1、通知用户
有些服务需要一段时候后才会处理,比如订单处理,会先放到消息队列中,逐个处理,
如果处理失败(服务调用失败)需要及时通知用户,比xx分钟内到账、xx分钟内出票,如果服务调用失败,在回退方法中要通知用户。
如果是车票、电影票、充话费之类较为重要的,要在回退方法中记录日志,并调用短信接口及时告知用户出票失败、充值失败,退款预计xx小时内到账。
通知时,如果当前线程还要做一些操作,比如返回数据给上游服务,通知是一个单独的业务,可以新建一个线程来通知,不要阻塞当前线程。
2、通知系统管理员、运维
统计服务调用失败的次数,如果指定时间内服务调用失败次数达到指定值,或者指定时间内服务调用失败的比例达到指定值,就以短信或者email的方式通知运维、管理员。
可以写一个工具类,用一个静态变量记录服务调用总数,调用某服务一次就+1,再使用一个静态变量统计该服务调用失败的次数;
写一个springboot定时任务,比如每5min执行一次,检测调用总次数、服务调用失败比例,达到指定值就通知管理员、运维,
检测调用总次数是为了确认被调者是否可能出问题了,不能调用总数1、失败率100%就通知管理员,可能是用户自己的问题。
通知之后或者比例未达到指定值,将统计值清空,重新统计下一个5min。
需要做好日志记录,方便管理员找出问题。
比如说被调用的服务集群挂了,不能每隔5min就通知管理一次,人家都开始处理了,你还一直通知。
可以在管理面板中提供按钮,点击可以关闭、开启通知管理员的功能,管理员收到故障通知后在面板中关闭通知管理员的功能,开始排查问题,解决后再开启通知管理员的功能。
也可以通知管理员之前先检测redis上有没有某个键值对,有就说明通知过了,不再通知;没有就设置此键值对,并指定过期时间,再通知管理员。比如过期时间设置为2h,2h通知一次。
Hystrix参数设置
Hystrix的参数配置可以写在@HystrixCommand(标注在方法上,只对该方法有效)、@DefaultProperties(标注在类上,对类中所有的方法都有效)注解中,
但配置自然是写在配置文件中好些,官方也是写在配置文件中的。
Hystrix的配置是写在消费者中的,常用配置如下:
hystrix:
command:
default:
execution:
#是否启用超时,默认true,一般都是设置为true
#timeout:
#enabled: true
isolation:
#有2种隔离策略:THREAD 线程池(默认)、SEMAPHORE 信号量
strategy: THREAD
thread:
#超时时间,默认1000,ms
timeoutInMilliseconds: 4000
#semaphore:
#设置信号量最大值,默认10
#maxConcurrentRequests: 100
上面使用的是hystrix,参数前缀是hystrix ;如果使用feign自带的hystrix,参数前缀是 feign: hystrix
超时时间指的是@HystrixCommand标注的方法执行的时间,如果使用的是Feign自带的Hystrix,指定的是服务调用的时间。
超时自动返回失败,如果将超时时间关闭,则一直等待服务调用完成,不会超时。一般都开启超时时间。
隔离策略即服务限流,消费者一般都会对提供者发起多个服务调用请求,消费者可以设置服务限流,限制本身对提供者的并发请求数。有2种策略
(1)THREAD 线程池,也叫做线程隔离,默认的隔离策略
为每个被调用的服务都创建一个线程池,将每个服务调用请求都包装为一个线程,放到线程池中。
线程池中的服务调用请求都是正在执行的,若线程池满了,放在队列中排队等待,若队列也满了,则后续对该被调者的请求直接快速失败。
Hystrix使用的是jdk自带的线程池,不是tomcat的线程池。并发执行的服务调用数取决于线程池能容纳的线程数。
(2)SEMAPHORE 信号量
信号量即可同时处理的请求个数,默认值10。
调用一次该服务,将信号量-1,一个调用请求结束将信号量+1,信号量为0时不再接受对该服务的调用请求,直接快速失败。
信号量适用于高并发服务调用,比如每秒数千次服务调用,因为使用线程池会导致线程池中同时存在几千个线程,开销巨大。
不用将服务调用请求包装为单独的线程,速度更快,但信号量一般只用于非网络调用。
快速失败是指不调用服务提供者,直接服务降级,执行回退方法。
如果要设置Hystrix的更多参数:
github上搜hystrix找到官方 -> WiKi -> 点击右侧的目录中的Configuration即可查看hystrix全部参数的介绍
直达车 https://github.com/Netflix/Hystrix/wiki/Configuration
SpringCloud Netflix Hystrix的更多相关文章
- SpringCloud学习笔记(五、SpringCloud Netflix Hystrix)
目录: Hystrix简介 线程隔离:线程池.信号量 服务降级.服务熔断.请求缓存.请求合并 Hystrix完整流程.Hystrix属性值 注解方式实现Hystrix Hystrix Dashboar ...
- Spring Cloud 系列之 Netflix Hystrix 服务容错
什么是 Hystrix Hystrix 源自 Netflix 团队于 2011 年开始研发.2012年 Hystrix 不断发展和成熟,Netflix 内部的许多团队都采用了它.如今,每天在 Netf ...
- Spring Cloud 系列之 Netflix Hystrix 服务监控
Actuator Hystrix 除了可以实现服务容错之外,还提供了近乎实时的监控功能,将服务执行结果和运行指标,请求数量成功数量等等这些状态通过 Actuator 进行收集,然后访问 /actuat ...
- springCloud学习3(Netflix Hystrix弹性客户端)
springcloud 总集:https://www.tapme.top/blog/detail/2019-02-28-11-33 本次用到全部代码见文章最下方. 一.为什么要有客户端弹性模式 所 ...
- SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级
什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...
- SpringCloud系列之服务容错保护Netflix Hystrix
1. 什么是雪崩效应? 微服务环境,各服务之间是经常相互依赖的,如果某个不可用,很容易引起连锁效应,造成整个系统的不可用,这种现象称为服务雪崩效应. 如图,引用国外网站的图例:https://www. ...
- springcloud学习04- 断路器Spring Cloud Netflix Hystrix
依赖上个博客:https://www.cnblogs.com/wang-liang-blogs/p/12072423.html 1.断路器存在的原因 引用博客 https://blog.csdn.ne ...
- Spring-cloud (九) Hystrix请求合并的使用
前言: 承接上一篇文章,两文本来可以一起写的,但是发现RestTemplate使用普通的调用返回包装类型会出现一些问题,也正是这个问题,两文没有合成一文,本文篇幅不会太长,会说一下使用和适应的场景. ...
- java框架之SpringCloud(5)-Hystrix服务熔断、降级与监控
前言 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.不做任何处理的情况下,很容易导致服务雪崩. 服务雪崩:多个微服务之间调用的时候,假设 ...
随机推荐
- XSS攻击解决办法 Spring mvc databinder
XSS攻击解决办法 一.SpringMVC架构下@InitBinder方法 Controller方法的参数类型可以是基本类型,也可以是封装后的普通Java类型.若这个普通Java类型没有声明任何注解, ...
- Pikachu-Sql Inject(SQL注入)
在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞.一个严重的SQL注入漏洞,可能会直接导致一家公司破产!SQL注入漏洞主要形成的原因 ...
- jQuery笔记(五)jQuery表单验证
前言 上次我们说完jQuery中的动画之后,我们再来看一种jQuery在Web网页应用最为广泛的一种形式,这就是jQuery对表单的操作,通过jQuery对表单的操作,可以有效的提高用户体验.在此之前 ...
- 随机定时修改密码change_passwd.sh
change_passwd.sh #!/bin/sh /usr/bin/chattr -i /etc/passwd /etc/shadow /etc/group /etc/gshadow /usr/b ...
- Android电源管理基础知识整理
前言 待机.睡眠与休眠的区别? Android开发者官网当中提到"idle states",该如何理解,这个状态会对设备及我们的程序造成何种影响? 进入Doze模式中的idle状态 ...
- 0级搭建类008-Ubuntu Server Linux安装 (18.04.2) 公开
项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...
- python递归删除目录本身以及目录下文件
import os def local_rm(dirpath): if os.path.exists(dirpath): files = os.listdir(dirpath) for file in ...
- linux 配置compoer
配置默认php 删除 rm -f /usr/bin/php 改到php7.3版本的composer /bin/php /usr/bin/php 多版本支持 配置php7专用composer70 cd ...
- mybatis第一天02
mybatis第二天02 1.映射文件之输入输出映射 1.1映射文件之输入映射类型(parameterType) 1.1.1简单类型 当parameterType为简单类型时,我们只需要直接填写“in ...
- eclipse将项目打包成jar在linux中运行
最近因为项目需要,做了几个外挂程序做数据传输,涉及到项目打包操作,在此记录一下打包步骤和其中出现的问题. 1.首先右键项目文件夹,点击export,弹出如下选择框,在其中输入jar搜索,并选择JAR ...