赞
踩
在使用 Hystrix组件之前呢,先了解一些概念。
何为雪崩:小雪球,越滚越大,灾难性事故!
在微服务之间进行服务调用时,由于某一个服务不可用(故障),导致其他正常的服务调用线程积压,从而引发其自身也不可用,并且还会蔓延到其他正常的服务上,最终导致所有服务不可用的现象,称为
雪崩效应,即服务雪崩
。
简单来说,服务雪崩:一个服务不可用会越滚越大,最终整个系统所有服务均不可用的现象。
雪崩效应的原因是微服务之间的相互依赖。
一个服务往往涉及多个微服务的协作。这种相互依赖的情况称之为服务依赖
。
服务雪崩的解决措施就是服务熔断、服务降级。
“熔断器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控或者某个异常条件被触发,直接熔断整个服务,向调用方法返回一个符合预期的、可处理的备选响应(FallBack),
而不是长时间的等待或者抛出调用方法无法处理的异常,就保证了服务调用方的线程不会被长时间占用,避免故障在分布式系统中蔓延,乃至雪崩。如果目标服务情况好转则恢复调用。
服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此缓解服务器的压力,以保证核心任务的进行。同时保证部分甚至大部分任务客户能得到正确的相应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。
降级服务也有不同的层级。比如,电商网站在双十一抢购时,可以不展示广告等,仅展示重要信息。
简单来说,服务降级:为保证系统核心服务的正常运行,选择关闭系统一些中边缘服务(直接返回拖底数据,即响应一下静态反馈数据),来防止防止系统的整体缓慢甚至崩溃的一种技术手段。
区别在于熔断是对调用链路的保护,而降级是对系统过载的一种保护处理。
相同点
不同点
出发的原因不同
服务熔断一般是某个服务(多指当前调用下的服务提供者)故障引起,一般都是服务基于策略的自动触发。
服务降级一般是从整体负荷考虑(cpu、内存等)完全靠人手动升降级服务显然不可能。
管理目标的层次不太一样
熔断其实是一个框架级的处理,每个微服务都需要(无层级之分)。
降级一般需要对业务有层级之分。
Hystrix(/hɪst'rɪks/)
翻译过来是 豪猪的意思。
Hystrix 是 Netflix 针对微服务分布式系统采用的熔断保护组件,相当于电路中的保险丝。断路器使得微服系统可以在一些糟糕的情况下,仍然尽量保证系统的可用性。
在分布式系统中,许多服务依赖不可避免的会调用失败,超时、异常等,Hystrix能够保证在一个服务依赖出问题的情况下,不会导致整体服务失败,避免级联故障(服务雪崩现象),提高分布式系统的弹性。
在微服务架构下,很多服务都相互依赖,如果不能对依赖的服务进行隔离,那么服务本身也有可能发生故障,Hystrix 通过 HystrixCommand 对调用进行隔离,这样可以阻止故障的连锁效应,能够让接口调用快速失败并迅速恢复正常,或者回退并优雅降级。
解决服务雪崩问题主要是服务降级,主要包括:
触发 Hystrix服务降级的情况有:
在服务熔断中,使用的熔断器,也叫断路器,其英文单词为:Circuit Breaker
。
Hystrix的服务熔断机制,可以实现弹性容错;当服务请求情况好转之后,可以自动重连。通过断路的方式,将后续请求直接拒绝,一段时间(默认5秒)之后允许部分请求通过,如果调用成功则回到断路器关闭状态,否则继续打开,拒绝请求的服务。
状态机有3个状态:
搭建项目,传送门:Eureke服务治理中心
在服务调用方引入依赖,这里User服务调用Order服务。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
调用方启动类使用 @EnableCircuitBreaker注解
,表示开启 Hystrix断路器。
也可以使用 @SpringCloudApplication注解
,是它们三个的组合。
//@SpringBootApplication //@EnableEurekaClient //@EnableCircuitBreaker // 表示开启 Hystrix断路器 @SpringCloudApplication public class UserApplication { // 负载均衡 @LoadBalanced @Bean public RestTemplate initRestTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(UserApplication.class, args); } }
(1)在单个方法上
在需要使用熔断调用函数的方法上使用 @HystrixCommand 注解
并指定 fallbackMethod 属性,定义熔断后的调用函数。
注意:
方法和熔断函数的参数要保持一致,返回值类型必须相同。
(2)在 controller上
使用 @DefaultProperties注解
当需要熔断的函数过多的使用,在使用单个的熔断,就过于繁琐,每一个方法都需要一个熔断,所以可以在类上使用全局的熔断。
使用注解
@DefaultProperties
:使用在类上,声明全局的熔断函数@HystrixCommand
:使用在方法上,默认使用全局的熔断 ,也可以通过fallbackMethod 属性指明自己的熔断函数注意:
在全局的熔断函数不需要参数,返回String。
@RestController @RequestMapping("/hystrix") @DefaultProperties(defaultFallback = "fallbackMethod") public class User2Controller { @Autowired private RestTemplate restTemplate; @GetMapping("/get1/{id}") @HystrixCommand public String get1(@PathVariable Long id) { String url = "http://ORDER/order/get1/" + id; String res = restTemplate.getForObject(url, String.class); return res; } public String fallbackMethod(){ return "网络开小差了,请稍后再试!"; } @PostMapping("/post1") @HystrixCommand(fallbackMethod = "post1fallback") public ResponseEntity<OrderDO> post1(@RequestBody OrderDO orderDO) { String url = "http://ORDER/order/post1"; OrderDO res = restTemplate.postForObject(url, orderDO, OrderDO.class); return ResponseEntity.ok(res).; } public ResponseEntity<OrderDO> post1fallback(OrderDO orderDO){ System.out.println("添加失败,服务正忙,请稍后再试!"); return ResponseEntity.ok(new OrderDO()); } }
两种方式就写一起测试了,单个方法上,返回值类型简单处理了。Order服务不需要改动,测试时,将Order服务做重启,下线等模拟故障,访问 User服务就会看到如下信息。进去了熔断处理,而不会像之前系统报错。
4、修改 Hystrix默认的超时时间
当User服务调用Order服务资源时 Hystrix得默认超时时间是1s。可以在调用方的配置文件中修改。
hystrix:
command:
default:
execution:
isolation:
thread:
# 设置hystrix超时时间(单位毫秒),默认1000ms
timeoutInMilliseconds: 3000
circuitBreaker:
errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%
sleepWindowInMilliseconds: 5000 # 熔断后休眠时长,默认值5秒
requestVolumeThreshold: 20 # 熔断触发最小请求次数,默认值是20
参考文章:
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。