Skip to content
On this page

限流要点

分布式遇到的问题

服务可用性问题

  • 如果微服务架构下流服务不可用,就会出现线程池里所有线程都因等待响应而被阻塞,从而造成整个服务链路不可用,进而导致整个系统服务雪崩

  • 服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用主键方法的过程,就叫服务雪崩效应

导致服务不可用的原因:

  • 激增流量
    • 激增流量导致系统CPU/Load飙高,无法正常处理请求
    • 激增流量打垮冷系统(数据库连接为创建,缓存未预热)
    • 消息投递速度过快,导致消息处理积压

在服务提供者不可用的时候,会出现大量重试的情况:用户重试,代码逻辑重试,这些重试最终导致:进一步加大请求流量。所以归根到底导致雪崩效应的最根本原因是:大量请求线程同步等待造成的资源耗尽,当服务调用者使用同步调用时,会禅城大量的等待线程占用系统的资源,一旦线程资源被耗尽,服务调用者提供的服务也将处理不可用状态,于是服务雪崩效用产生了

解决方案:容错

常见的容错机制

  • 超时机制

    在不做任何处理的情况下,服务提供者不可用会导致消费者请求线程强制等待,而造成系统资源耗尽,加入超时机制,一旦超时,就会释放资源。由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题

  • 服务限流

    在服务开放的接口进行限流操作,当大量请求进来,可以选择直接拒绝或者等待操作

  • 隔离

    • 线程隔离

    用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,则会进行降级处理,用户的请求就不会阻塞,至少可以看到一个执行结果(至少返回一个状态码或者提示信息),而不是无休止的等待或者重试到系统崩溃

    • 信号隔离

    信号隔离也可以用于限制并发访问,防止阻塞扩散,与线程隔离最大不同在于依赖代码的线程依然是请求线程(该线程需要通过信号申请,如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。信号量的大小可以动态调整,线程池的大小不可以)

  • 服务熔断

    远程服务不稳定或者网络抖动时,暂时关闭,就叫服务熔断

    实时监测应用,如果发现在一定时间内失败次数/失败率达到一定阈值,就“跳闸”,断路器打开——此时,请求直接返回,而不去调用原本调用的逻辑。跳闸一段时间后(例如10秒),断路器会进入半开状态,这是一个瞬间态,此时允许一次请求调用该调的逻辑,如果成功,则断路器关闭,应用正常调用;如果调用依然不成功,断路器继续回到打开状态,过段时间再进入半开状态尝试——通过”跳闸“,应用可以保护自己,而且避免浪费资源;而通过半开的设计,可实现应用的“自我修复“。

  • 服务降级

    有服务熔断,必然有服务降级

    所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。如此处理,虽然服务水平下降,但好歹可用,比直接宕机要好