我们会根据业务的重要性,进行不同的权重分布。以去哪儿的航班列表页和 OTA 页为例,航班列表页不一定会有用户转化,OTA 页的用户转化可能性更大,所以我们会把 OTA 页的权重设置得更高。
正常的用户,我们会尽量保证计算能力,而抓取的用户,我们则尽量减少资源消耗,设置的权重就比较少,最终计算出来的优先级,就会聚合出来下图这样的一组数。
按照前面的几种维度,数值都一样的情况下,在一个用户是 NORMAL 另一个是
ATTACH 时,一旦出现限流,优先限制的流量就是权重比较小的这部分。
(去哪儿网动态限流核心算法公式,仅供参考)
通过动态限流的形式,流量从头到尾地传递到了每一层系统当中,系统在识别完流量后,我们可以很清晰地看到整个链路上的流量分布,一旦某个流量出现问题,或者是整体流量突然上涨时,我们很快就能知道出现异常了,也方便我们采取其他兜底措施。
兜底限流主要是应对流量突增。比如,滑动窗口是 2 秒,前面的流量可能都是 0 QPS ,当某一秒的 QPS 到达 1000 时,如果动态限流设置的是 500,那这个地方就会被击穿,这种情况对于系统来说是有一定的风险的,所以我们会启动兜底限流进一步地去做系统防护。
通过动态限流的计算,已经打破了集群隔离,此时我们会考虑,以前的集群隔离是否还有必要存在?从某种程度来说,是不需要存在的。我们举一些具体的例子来看一下。
比如,图中可以看到,不同的集群上机器的流量, load 大小有明显的差别,有的 load 平均下来最大都能达到 16,但是有一些它的 load 最大只有 4 ,不同的分组上,业务流量转化率差别很大。同时,机器分布又很多,机器投入产出比并不对等。
在动态限流已经能够保护核心流量的前提下,我们就需要打破集群隔离,做集群合并。集群合并完之后的效果也是不错的,上面图中的这台机器,集群合并之后它的 load 降低了不少。
除了上述动态限流的一系列动作外,我们还有很多其他的措施,比如,系统请求的合并和缓存处理。
如上图所示,同样的请求用户 1 和用户 3 ,在短时间内或者是同时进入到系统后,它的底层处理商尤其是数据适配层拿取数据是一样的,则没有必要在短时间内重复计算一次来增加对于外部系统的影响。我们是让请求 3 强等前面的请求,去缓存中直接拿数,以降低容量要求。当下游系统没有正常返回时,或是出现限流的情况下,我们用缓存来保证整个服务的运行。