Skip to content
0

服务容错

服务之间的依赖关系导致调用失败,解决的方式通常是:限流 -> 熔断 -> 隔离 -> 降级

限流

当高并发或者瞬时高并发时,为了保证系统的稳定性、可用性,系统以牺牲部分请求为代价或者延迟处理请求为代价,保证系统整体服务可用。

限流算法

令牌桶算法

先有一个桶,系统按照固定速度往桶里面放入令牌,如果桶满了则不再放入。当请求到来时,从桶中取出令牌,获得了令牌的请求可以继续处理,没有令牌的请求就拒绝服务。

在没有请求时,桶会积累一些令牌。当有突发流量时,只要令牌足够,就能一次全部处理。因此,令牌桶算法可以处理突发流量。

令牌桶算法是网络流量整形和速率限制中最常用的一种算法。

漏桶算法

水(请求)先进入到桶里,桶按一定的速度(接口有响应速率)出水,当水流速度过大(请求过多)时,桶会直接溢出(访问频率超过接口响应速率),然后拒绝请求。因为桶的出水速率是固定的,所有漏桶算法对突发流量的处理缺乏效率。

计数器算法

计数器限流算法也是比较常用的,主要用来限制总并发数,比如数据库连接池大小、线程池大小、程序访问并发数等都是使用计数器算法。也是最简单粗暴的算法。

  • 统计当前并发数,超过阈值直接返回系统繁忙等响应。
  • 基于信号量控制并发次数,超过阈值进入到队列中排队等待,可以给队列设置一个最大值,超过最大值则拒绝请求。
  • 固定大小的线程池。

熔断

当错误数超过阈值时快速失败,不调用后端服务,同时隔一段时间放几个请求去重试后端服务是否能正常调用,如果成功则关闭熔断状态,失败则继续快速失败。熔断流程通常使用断路器模式实现。

断路器模式有3个基本状态和1个基本动作trip:

  • close 状态:客户端的请求直接无障碍通过断路器到达服务端,服务端的响应也直接无障碍通过断路器返回给客户端。即畅通无阻。
  • open 状态:客户端的请求经过断路器后直接返回给客户端,不会将请求转到服务端。
  • trip:在 close 状态下,如果服务端持续超时报错,达到规定的阈值后断路器就发生trip,之后断路器由close状态变为open状态。
  • half-open 状态:在 open 状态下,断路器会每隔一段时间尝试调用服务端,如果服务端正常则断路器由open状态变为close状态。在断路器重试期间,其处于half-open(半开)状态。

隔离

把每个依赖或调用的服务都隔离起来,防止级联失败引起整个服务不可用。比如使用线程池来隔离资源,一个服务里面要调用另外两个服务A和B,如果这两个服务都使用同一线程池,当服务A卡住时,资源不会被释放,后面的请求又来了,全都卡在这里导致线程池资源耗尽,也影响了服务B的可用性。而如果隔离起来,假设现在有100个线程可用,给A服务和B服务各分配50个线程,这样即使A服务挂了,B服务依然可用。

降级

服务失败或异常后,返回指定的默认消息。

实现技术

Hystrix

Sentinel