4.1 微服务容错简介
在⾼并发访问下,⽐如天猫双11,流量持续不断的涌⼊,服务之间的相互调⽤频率突然增加,引发系统负载过⾼,这时系统所依赖的服务的稳定性对系统的影响⾮常⼤,⽽且还有很多不确定因素引起雪崩,如⽹络连接中断,服务宕机等。⼀般微服务容错组件提供了限流、隔离、降级、熔断等⼿段,可以有效保护我们的微服务系统。
4.1.1 隔离
微服务系统A调⽤B,⽽B调⽤C,这时如果C出现故障,则此时调⽤B的⼤量线程资源阻塞,慢慢的B的线程数量持续增加直到CPU耗尽到100%,整体微服务不可⽤,这时就需要对不可⽤的服务进⾏隔离。
1.线程池隔离
线程池隔离就是通过Java的线程池进⾏隔离,B服务调⽤C服务给予固定的线程数量⽐如12个线程,如果此时C服务宕机了就算⼤量的请求过来,调⽤C服务的接⼝只会占⽤12个线程不会占⽤其他⼯作线程资源,因此B服务就不会出现级联故障。线程池隔离原理,如图4-2所示。
2.信号量隔离
隔离信号量隔离是使⽤Semaphore来实现的,当拿不到信号量的时候直接拒接因此不会出现超时占⽤其他⼯作线程的情况。代码如下。
Semaphore semaphore = new Semaphore(10,true);
//获取信号量
semaphore.acquire();
//do something here
//释放信号量
semaphore.release();
3.线程池隔离和信号量隔离的区别
线程池隔离针对不同的资源分别创建不同的线程池,不同服务调⽤都发⽣在不同的线程池中,在线程池排队、超时等阻塞情况时可以快速失败。线程池隔离的好处是隔离度⽐较⾼,可以针对某个资源的线程池去进⾏处理⽽不影响其它资源,但是代价就是线程上下⽂切换的 overhead ⽐较⼤,特别是对低延时的调⽤有⽐较⼤的影响。⽽信号量隔离⾮常轻量级,仅限制对某个资源调⽤的并发数,⽽不是显式地去创建线程池,所以 overhead ⽐较⼩,但是效果不错,也⽀持超时失败。
类别 | 线程池隔离 | 信号量隔离 |
---|---|---|
线程 | 与调⽤线程不同,使⽤的是线程池创建的线程 | 与调⽤线程相同 |
开销 | 排队,切换,调度等开销 | ⽆线程切换性能更⾼ |
是否支持异步 | ⽀持 | 不支持 |
是否支持超时 | ⽀持 | 支持 |
并发支持 | ⽀持通过线程池大小控制 | ⽀持通过最⼤信号量控制 |
4.1.2 熔断
当下游的服务因为某种原因突然变得不可⽤或响应过慢,上游服务为了保证⾃⼰整体服务的可⽤性,不再继续调⽤⽬标服务,直接返回,快速释放资源。如果⽬标服务情况好转则恢复调⽤。熔断器模型,如图所示。
熔断器模型的状态机有3个状态。
-
Closed:关闭状态(断路器关闭),所有请求都正常访问。
-
Open:打开状态(断路器打开),所有请求都会被降级。熔断器会对请求情况计数,当⼀定时间内失败请求百分⽐达到阈值,则触发熔断,断路器会完全打开。
-
Half Open:半开状态,不是永久的,断路器打开后会进⼊休眠时间。随后断路器会⾃动进⼊半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会关闭断路器,否则继续保持打开,再次进⾏休眠计时。
4.1.3 降级
降级是指当⾃身服务压⼒增⼤时,系统将某些不重要的业务或接⼝的功能降低,可以只提供部分功能,也可以完全停⽌所有不重要的功能。⽐如,下线⾮核⼼服务以保证核⼼服务的稳定、降低实时性、降低数据⼀致性,降级的思想是丢⻋保帅。
举个例⼦,⽐如,⽬前很多⼈想要下订单,但是我的服务器除了处理下订单业务之外,还有⼀些其他的服务在运⾏,⽐如,搜索、定时任务、⽀付、商品详情、⽇志等等服务。然⽽这些不重要的服务占⽤了JVM的不少内存和CPU资源,为了应对很多⼈要下订单的需求,设计了⼀个动态开关,把这些不重要的服务直接在最外层拒绝掉。这样就有跟多的资源来处理下订单服务(下订单速度更快了)
4.1.4 限流
限流,就是限制最⼤流量。系统能提供的最⼤并发有限,同时来的请求⼜太多,就需要限流,⽐如商城秒杀业务,瞬时⼤量请求涌⼊,服务器服务不过来,就只好排队限流了,就跟去景点排队买票和去银⾏办理业务排队等号道理相同。下⾯介绍下四种常⻅的限流算法。
1.漏桶算法
漏桶算法的思路,⼀个固定容量的漏桶,按照常量固定速率流出⽔滴。如果桶是空的,则不需流出⽔滴。可以以任意速率流⼊⽔滴到漏桶。如果流⼊⽔滴超出了桶的容量,则流⼊的⽔滴溢出了(被丢弃),而漏桶容量是不变的。
2.令牌桶算法
令牌桶算法:假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌。桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝。当⼀个n个字节⼤⼩的数据包到达,将从桶中删除n个令牌,接着数据包被发送到⽹络上。如果桶中的令牌不⾜n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待)。令牌桶限流原理,如图所示。
令牌桶限流服务器端可以根据实际服务性能和时间段改变⽣成令牌的速度和⽔桶的容量。 ⼀旦需