需求缘起
产品需要在用户购买的资源支持按需付费。这样,用户可以在短时间内申请大量资源使用,使用完成后,又集中大量的释放资源。对于我们后台服务来说,会带来短时间内大量并发的申请和释放资源的集中请求。这就需要合适的流控策略来限制、缓解、放弃请求并友好的提示用户重试。
问题分解
- 用户流量控制
- 后端服务排队机制
- 友好的请求reset
用户流量控制
我们团队的系统属于后端 web server,前面有用户控制台和 openapi层,后面是数据库层。
控制台和 openapi层可以限制用户一段时间内申请的资源总数。
后端 web server 根据控制台和 openapi层每个用户的请求数限制,设置合理的时间窗口内的请求阈值。
流量预警和限流方案中,比较常用的有两种。第一种是滑窗模式,通过统计多个单元时间内的访问次数来进行控制,当单位时间内的访问次数达到所设置的阈值时进行限流。第二种,为响应模式,通过控制当前活跃的请求数来进行流量控制。下面简要分析下两种方案。
滑窗模式
在每次有请求访问时,系统判断前N个时间单位总访问量是否超过了设置的阈值,若超过则不允许此次访问的执行。
该模式存在几个问题。首先,阈值设置为多少是合理的?我们可以通过线下的压测和模拟测试为依据进行评估。不过这跟线上系统还是会存在差异,比如,硬件性能,同一个系统在不同时刻的负载不同等等。所以无法做到100%的精确评估。其次,滑窗模式可能会出现单位时间的前半段请求大量涌入,而后半段系统拒绝所有请求的情况。
响应模式
每次请求访问时,系统通过判断正在执行的访问数是否达到我们设置的阈值来决定是否限流。该模式只关心当下正在处理中的请求,对于已经处理完毕的请求则不再关心了。
后端服务排队机制
当N个时间单位的请求数量达到峰值时,使用前述的两种模式的限流,都会将大量的请求挡住。这样会拒绝大量用户的正常访问请求,造成用户体验不佳。此时,后端服务可以使用排队机制,将访问的请求分批次排队,迁移批次的请求处理完成后,再从队列中拿出下一批次的请求进行处理。
排队机制主要用来应对尖峰时刻的大量请求,不被大量的拒绝。如果系统有持续的超出系统承载能力的请求,则可能会造成系统雪崩,永远也处理不完队列中的请求。
友好的请求拒绝
根据系统当前的承载能力评估出最大的请求阈值,一旦当前访问量超出这个阈值,则拒绝请求并友好的提示用户稍后重试。这是系统的性能极限,为避免系统崩溃,必须果断拒绝请求。