原创作者:田超凡(程序员田宝宝)
版权所有,引用请注明原作者,严禁复制转载
Part 1 理论部分
1 什么是微服务系统中的高可用?
在复杂的大型微服务系统中,高可用相关的技术方案非常重要,高可用架构中非常重要的一个环节,就是如何将微服务系统中的各个服务打造成高可用服务集群,从而可以从容应对在微服务环境下可能会遇到的各种各样的问题,避免整个微服务系统被某个服务的故障给拖垮,比如:服务间的调用超时、调用失败等等。
要解决这些棘手的、影响微服务系统可用性的问题,就要涉及到高可用解决方案中很多非常重要的技术点,包括:
资源隔离、
服务限流和过载保护、
熔断、
优雅降级、
容错、
超时控制、
监控运维等。
2 什么是服务雪崩效应?
服务雪崩效应产生于所有服务的请求都堆积在同一个线程池中的情况,因为所有的请求都是同一个线程池进行处理,如果在高并发情况下,所有的请求全部访问某个服务的同一个接口,达到线程池默认的最大极限后,会导致其他的服务也无法访问,这就是服务雪崩效应。
解决服务雪崩效应可以使用服务隔离机制实现(线程池隔离和信号量拦截)。
3 什么是服务降级?
在高并发情况下,为了防止用户一直等待,当响应时间过长时(可以设置一个最大响应等待时间),需要使用服务降级的方式调用fallBack方法,直接返回一个友好的提示给客户端,从而减少响应时间。
4 什么是服务熔断?
服务熔断的目的是为了保护服务,在高并发情况下,如果请求数量达到了服务能承受的最大极限(这个最大极限可以自行手动设置,也叫最大阈值),如果流量超出了设置的最大阈值,则直接拒绝访问,保护当前服务。然后可以使用服务降级来返回一个友好提示,所以推荐服务熔断和服务降级一起使用。
5 什么是服务隔离?
默认情况下,只有一个线程池来维护所有的服务接口,如果大量的请求访问同一个服务接口,达到Tomcat线程池默认的最大极限后,可能会导致其他服务也无法访问。因此需要基于服务隔离机制保证服务和服务之间相互独立,互不影响。
可以使用独立的线程池实现服务隔离,相当于每个接口(服务)都有自己独立的线程池,因为所有线程池互不影响,这样也就可以用来解决服务雪崩效应。
服务隔离最常用的实现方案有两种:线程池隔离和信号量拦截。
线程池隔离:每个服务接口都有自己独立的线程池,线程池之间完全隔离,互不影响,这样即使一个服务的线程池满了也不会影响到其他服务。
信号量拦截:使用一个原子计数器(或信号量)记录当前运行的线程个数,当请求进来时先判断计数器的数值,若超过了设置的最大线程数则直接拒绝该请求,若没有超过则放行,然后计数器+1,当请求返回响应成功后计数器-1。
6 什么是服务限流?
服务限流就是对每个接口的访问量进行限制,常用的服务限流算法有漏桶、令牌桶,计数器也可以实现粗暴限流。
7 什么是Hystrix?
Hystrix是由国外知名的影视网站Netflix提供的开源的高可用断路器框架,Hystrix能够完美地解决微服务系统中打造高可用服务集群所要面对的一系列技术难题。
在微服务架构中,我们把每块业务都拆成单个的服务模块,当需求需要的时候,服务之间可以互相调用,但是,由于网络原因或其它的一些因素,有可能会出现服务不可用的情况,当某个服务出现问题时,如果其他服务继续调用这个服务,就有可能出现线程阻塞,但如果同时有大量的请求,就会造成线程资源被用完,这样就可能会导致服务瘫痪,由于服务间会相互调用,很容易造成蝴蝶效应,导致整个系统宕掉。因此,就有人提出用断路器来解决这一问题。
Hystrix"豪猪",具有自我保护的能力,Hystrix可以通过以下几种机制来解决服务雪崩效应:
1 资源隔离:包括线程池隔离和信号量拦截,限制调用分布式服务的资源运行,某一个调用的服务出现问题不会影响到其他服务调用。
2 降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。
3 熔断:当失败率达到阈值自动触发服务降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败能够快速恢复。
4 缓存:提供了请求缓存、请求合并实现。
Part 2 实践部分
Hystrix环境搭建
Maven依赖信息
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <!-- ++hystrix++断路器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-++netflix++ -++hystrix++</artifactId> </dependency> |
开启Hystrix断路器
|----------------------------------------------------------------------------------------------------------------------------------------|
| ++feign++ : hystrix: enabled: true ####++hystrix++ 禁止服务超时时间 ++hystrix++ : command: default: execution: timeout: enabled: false |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| @SpringBootApplication @EnableEurekaClient @EnableFeignClients @EnableHystrix public class AppOrder { public static void main(String[] args) { SpringApplication.run(AppOrder.class , args); } } |
服务降级处理
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| @HystrixCommand(fallbackMethod = "orderToUserInfoFallback") @GetMapping("/orderToUserInfo") public ResponseBase orderToUserInfoHystrix() { System.out .println("orderToUserInfo:" + "当前线程池名称:" + Thread.currentThread().getName()); return memberServiceFeigin.getUserInfo(); } @RequestMapping("/orderToUserInfoFallback") public ResponseBase orderToUserInfoFallback() { return setResultError("系统错误!!!!"); } |
Fallback回调
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| @RequestMapping("/orderToUserInfo") public ResponseBase orderToUserInfo() { return memberServiceFeigin.getUserInfo(); } @Component public class MemberServiceFallback extends BaseApiService implements MemberServiceFeigin { public ResponseBase getUserInfo() { // 服务降级处理 return setResultError("系统错误,请稍后重试!"); } } |
本文部分素材转载自蚂蚁课堂