容错

在一个分布式系统里,一个服务往往要调用多个服务,可能存在某个服务调用失败, 比如超时、异常等,

要使用容错框架保证在某些服务调用出问题时,不会拖垮整个调用链路,系统依然可用。

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的更多相关文章

  1. SpringCloud学习笔记(五、SpringCloud Netflix Hystrix)

    目录: Hystrix简介 线程隔离:线程池.信号量 服务降级.服务熔断.请求缓存.请求合并 Hystrix完整流程.Hystrix属性值 注解方式实现Hystrix Hystrix Dashboar ...

  2. Spring Cloud 系列之 Netflix Hystrix 服务容错

    什么是 Hystrix Hystrix 源自 Netflix 团队于 2011 年开始研发.2012年 Hystrix 不断发展和成熟,Netflix 内部的许多团队都采用了它.如今,每天在 Netf ...

  3. Spring Cloud 系列之 Netflix Hystrix 服务监控

    Actuator Hystrix 除了可以实现服务容错之外,还提供了近乎实时的监控功能,将服务执行结果和运行指标,请求数量成功数量等等这些状态通过 Actuator 进行收集,然后访问 /actuat ...

  4. springCloud学习3(Netflix Hystrix弹性客户端)

    springcloud 总集:https://www.tapme.top/blog/detail/2019-02-28-11-33 本次用到全部代码见文章最下方. 一.为什么要有客户端弹性模式   所 ...

  5. SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级

    什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...

  6. SpringCloud系列之服务容错保护Netflix Hystrix

    1. 什么是雪崩效应? 微服务环境,各服务之间是经常相互依赖的,如果某个不可用,很容易引起连锁效应,造成整个系统的不可用,这种现象称为服务雪崩效应. 如图,引用国外网站的图例:https://www. ...

  7. springcloud学习04- 断路器Spring Cloud Netflix Hystrix

    依赖上个博客:https://www.cnblogs.com/wang-liang-blogs/p/12072423.html 1.断路器存在的原因 引用博客 https://blog.csdn.ne ...

  8. Spring-cloud (九) Hystrix请求合并的使用

    前言: 承接上一篇文章,两文本来可以一起写的,但是发现RestTemplate使用普通的调用返回包装类型会出现一些问题,也正是这个问题,两文没有合成一文,本文篇幅不会太长,会说一下使用和适应的场景. ...

  9. java框架之SpringCloud(5)-Hystrix服务熔断、降级与监控

    前言 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.不做任何处理的情况下,很容易导致服务雪崩. 服务雪崩:多个微服务之间调用的时候,假设 ...

随机推荐

  1. python全栈学习 day04

    列表基本操作: #!/usr/bin/env python # -*- coding:utf-8 -*- ''' li = ['alex', [1, 2, 3], 'wusir', 'godness' ...

  2. Nginx模块之ngx_http_proxy_module

    ngx_http_proxy_module模块: 示例: location / { proxy_pass http://localhost:8000; proxy_set_header Host $h ...

  3. HDU6537

    题意 英文 做法 将\(a_i>1\)的限制去掉,定义\(g(n,k)\) 显然有\[ans=\sum\limits_{i=0}^{k}(-1)^i \binom{k}{i}g(n,k-i)\] ...

  4. PAT (Basic Level) Practice (中文)1043 输出PATest (20 分)

    给定一个长度不超过 1 的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符已经输 ...

  5. 深入浅出Mybatis系列六-objectFactory、plugins、mappers简介与配置

    注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(五)---TypeHandler简介及配 ...

  6. .NetCore学习笔记:二、基于Dapper的泛型Repository

    为减少代码量,这里实现一个基于Dapper的泛型Repository. 这里需要引用Dapper.dll和Dapper.Contrib.dll. 接口定义: /// <summary> / ...

  7. nginx技术

    Nginx 处理高并发,单台服务器存在服务瓶颈 Nginx属于nio ,noblocking Io非阻塞式的 Apache属于Bio,Blocking IO 阻塞式的 安装部分 依赖安装:yum -y ...

  8. 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 ...

  9. 《深入理解java虚拟机》读书笔记五——第六章

    第六章 类文件结构 1.无关性的基石 各种不同平台的虚拟机与所有平台都统一使用程序存储格式——字节码是构成平台无关的基石. 实现语言无关性的基础仍然是虚拟机和字节码存储格式,Java虚拟机不和包括Ja ...

  10. H3C接口管理配置

    一.接口批量配置 当多个接口需要配置某功能(比如shutdown)时,需要逐个进入接口视图,在每个接口执行一遍命令,比较繁琐.此时,可以使用接口批量配置功能,对接口进行批量配置,节省配置工作量. 1. ...