控制应用程序的某个实例,某个独立的租户,或者某个整个服务对资源的消费。即使当需求增加而导致对资源的大量负载时,该模式也能够允许系统继续工作并满足SLA(服务等级协议)。
场景
云应用程序的负载经常依据活跃用户的数量或用户活动的类型而随着时间变化。例如,很多用户可能在工作时间活跃,或者在每个月月底的时候,可能会要求系统去处理开销很大的计算分析。也可能会存在突发的和意料之外的活动上的爆发点。如果系统的处理请求超出可用资源的容量,系统性能将会下降,并且甚至会发生故障。如果系统必须满足某个服务等级协议,这样的故障是不能够被接受的。
根据应用程序的业务目标,有很多策略可以用来处理云端上的负载变化。一个策略是使用自动扩展来满足特定时间上用户对于资源供给需求。当优化运行时成本时,该策略有持续满足用户需求的潜力。然而,当自动扩展可以触发额外资源的供给时,这种供给不是立即的。如果需求快速增加,会存在一个资源不足的时间窗口。
解决方案
一个替代的自动扩展策略是只允许应用程序使用有限定上限的资源,当限定达到时,对应用程序限流。系统应该监控资源时如何使用的,这样才能当利用率超过阈值时,系统能够限流某个或多个用户的请求。这将会使得系统继续工作,并且满足任何存在的服务等级协议(SLAs)。
系统可以实现一些限流策略,包括:
拒绝某个在特定时间段内已经访问每秒n次以上的系统APIs的单独用户。这就要求系统计量每个租户或用户使用的资源。
禁用或降级一些非必要的服务功能,以便必要的服务能够以足够的资源无碍的运行。例如,如果应用程序是视频流输出,可以切换到某个低分辨率。
使用负载分级来平滑活动的容量。在某个多租户环境中,该方式将会减少对于每个租户的性能。如果系统必须支持混合不同SLAs的租户,对于高价值的租户的工作可能会立即被处理。对于其它租户的请求可能会被延迟,当消除了待办任务时,才去处理这些请求。优先级队列模式可以用来实现这种方式。
延迟低优先级应用程序或租户的操作。这些操作可以被挂起或限制,产生一个异常来通知租户系统繁忙和该操作应该等会重试。
下图展示了应用程序使用3种特性的资源利用(内存,CPU,带宽等因素的组合)随时间变化的关系。特性是指一个功能范围,比如某个执行特定任务集合的组成部分,某个执行复杂计算的代码片段,或者某个提供服务比如内存内缓存的单元。这些特性被标识为A,B,和C。
上图展示了延迟操作的影响。T1时间开始之前,分配给所有使用这些特性的应用程序的资源达到某个阈值(资源利用限制)。在此刻,应用程序有耗尽可用资源的危险。在该系统中,特性B没有特性A或特性C重要,因此它将会暂时被禁用,并且它使用的资源会被释放。在T1时间和T2时间之间,使用特性A和特性B的应用程序继续正常运行。最终,特性A和C的资源利用减少到某个时间点,在T2时间,在该时间点有足够的能力重新启用特性B。
自动扩展和限流方式也可以组合起来,这样有助于保持应用程序响应和满足SLAs。如果预期到需求仍然会很高,在系统横向扩展时,限流会提供一个临时的解决方案。在此刻,系统全部功能可以被恢复。
下图展示了运行在系统里面的全部应用程序所使用的所有资源随着时间变化关系,并且说明了限流是如何能够和自动扩展相结合的。
在T1时间,达到由资源利用的软性限制标明的阈值。在此刻,系统可以开始横向扩展。然而,如果新的资源不能立即变得可用,那么现存的资源可能会被耗尽,并且系统可能发生故障。为了防止这种情况发生,如前面所述,系统会被暂时地限流。当自动扩展完成时并且额外的资源可用了,限流就可以放宽了。
考虑点
在实现该模式时,考虑下面几点:
限流一个应用程序和使用的策略是一种架构上的决策,该决策会影响整个系统的设计。应该在应用程序设计早期阶段就考虑限流,因为将限流增加到一个已经实现的系统是很不容易的。
限流必须被快速地执行。系统必须有能力检测到活动的增加并且做出相应地反应。在负载消除后,系统也必须能够快速还原到原始状态。这要求持续地捕捉和监控相关恰当的性能数据。
如果某个服务需要暂时地拒绝用户请求,它应该返回某个特定错误码,以便于客户端应用程序明白某个操作被拒绝的原因是因为限流了。客户端应用程序可以等一段时间在重试请求。
当系统自动扩展时,限流可以被用来作为一个临时的措施。如果活动上的爆发是突然的并且预期不会很长时间,在某些情况下,最好是简单地限流,而不是去扩展,,因为扩展会增加运行时成本。
当系统自动扩展时,如果限流被用来作为一个临时的措施,并且如果资源需求增长特别快,系统可能不会继续工作——即使处于限流模式中。如果不能接受这种,考虑维护大容量的储备并且配置更有侵略性的自动扩展策略。
什么时候使用?
适合:
为了保证系统持续工作来满足服务等级协议。
为了防止某个单一租户独占应用程序提供的资源。
为了处理活动上的爆发。
为了有助于优化系统的成本,通过限制最大资源标准。
文章来源:Throttling pattern