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服务熔断、降级与监控
前言 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.不做任何处理的情况下,很容易导致服务雪崩. 服务雪崩:多个微服务之间调用的时候,假设 ...
随机推荐
- python全栈学习 day04
列表基本操作: #!/usr/bin/env python # -*- coding:utf-8 -*- ''' li = ['alex', [1, 2, 3], 'wusir', 'godness' ...
- Nginx模块之ngx_http_proxy_module
ngx_http_proxy_module模块: 示例: location / { proxy_pass http://localhost:8000; proxy_set_header Host $h ...
- HDU6537
题意 英文 做法 将\(a_i>1\)的限制去掉,定义\(g(n,k)\) 显然有\[ans=\sum\limits_{i=0}^{k}(-1)^i \binom{k}{i}g(n,k-i)\] ...
- PAT (Basic Level) Practice (中文)1043 输出PATest (20 分)
给定一个长度不超过 1 的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符已经输 ...
- 深入浅出Mybatis系列六-objectFactory、plugins、mappers简介与配置
注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(五)---TypeHandler简介及配 ...
- .NetCore学习笔记:二、基于Dapper的泛型Repository
为减少代码量,这里实现一个基于Dapper的泛型Repository. 这里需要引用Dapper.dll和Dapper.Contrib.dll. 接口定义: /// <summary> / ...
- nginx技术
Nginx 处理高并发,单台服务器存在服务瓶颈 Nginx属于nio ,noblocking Io非阻塞式的 Apache属于Bio,Blocking IO 阻塞式的 安装部分 依赖安装:yum -y ...
- Leetcode Week4 Find Minimum in Rotated Sorted Array II
Question Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforeha ...
- 《深入理解java虚拟机》读书笔记五——第六章
第六章 类文件结构 1.无关性的基石 各种不同平台的虚拟机与所有平台都统一使用程序存储格式——字节码是构成平台无关的基石. 实现语言无关性的基础仍然是虚拟机和字节码存储格式,Java虚拟机不和包括Ja ...
- H3C接口管理配置
一.接口批量配置 当多个接口需要配置某功能(比如shutdown)时,需要逐个进入接口视图,在每个接口执行一遍命令,比较繁琐.此时,可以使用接口批量配置功能,对接口进行批量配置,节省配置工作量. 1. ...