8.3.1 限流算法

 

       说到限流算法,脑袋中不自觉就想到了漏 桶”与“令牌桶。诚然,两种限流的祖师级算法确有其 独到之处,其他实现比如滑动时间窗或者三色速率标记 法等,其实质还是“漏桶令牌桶的变种,要么是 将“漏桶容积换成了单位时间,要么是按规则将请求标
记颜色进行处理,底层还是令牌的思想。所以,掌 握“漏桶令牌桶算法原理,对理解其他限流算法有 一定帮助。
1.漏桶(Leaky Bucket
       漏桶的原型是一个底部有漏孔的桶,桶上方有一个 入水口,水不断地流进桶内,桶下方的漏孔就会以一个 相对恒定的速率漏水,在入大于出的情况下,桶在一段 时间之后就会被装满,这时候多余的水就会溢出;而在 入小于出的情况下,漏桶则不起任何作用。后来人们将 这个经典模型运用在网络流量整形上面,通过漏桶算法的约束,突发流量可以被整形为一个规整的流量,
如图 8-24所示。
 Spring Cloud Zuul限流
 
       当我们的请求或者具有一定体量的 数据流涌来的时候,在漏桶的作用下,流量被整形,不 能满足要求的部分被削减掉,所以,漏桶算法能够强制 限定流量速率。注意,在我们的应用中,这部分溢出的 流量是可以被利用起来的,并非完全丢弃,我们可以把 它们收集到一个队列里面,做流量排队,尽量做到合理 利用所有资源
2.令牌桶(Token Bucket
         令牌桶算法和漏桶算法有点不一样,桶里面存放令 牌,而令牌又是以一个恒定的速率被加入桶内,可以积 压,可以溢出。当我们的数据流涌来时,量化请求用于获取令牌,如果取到令牌则放行,同时桶内丢弃掉这个令牌;如果不能取到令牌,请求则被丢弃,如图所示。
 

Spring Cloud Zuul限流

 

由于令牌桶内可以存在一定数量的令牌,那么就可 能存在一定程度的流量突发,这也是决定漏桶算法与令 牌桶算法适用于不同应用场景的主要原因。

8.3.2 限流实战

    在Zuul中实现限流最简单的方式是使用定义Filter加 上相关限流算法,其中可能会考虑到Zuul的多节点部 署,因为算法的原因,这时候需要一个K/V存储工具 (推荐使用Redis,充分利用Redis单线程的特性,可以 有效避免多节点带来的一些问题)。当然如果Zuul是单 节点应用,限流方式的选择就会广得多,完全可以将相 关prefix放在内存之中,方便又快捷。
这里介绍一个开箱即用的工具,spring-cloud-zuul- ratelimit(https://github.com/marcosbarbero/spring-cloud-
zuul-ratelimit),它是一位国外友人专门针对Zuul编写 的限流库,提供多种细粒度策略:
        ·user:认证用户名或匿名,针对某个用户粒度进行 限流。
       ·origin:客户机ip,针对请求客户机ip粒度进行限 流。
        ·url:特定url,针对某个请求url粒度进行限流。
        ·serviceId:特定服务,针对某个服务id粒度进行限流。
         以及多种粒度临时变量存储方式:
      ·IN_MEMEORY:基于本地内存,底层是
      ConcurrentHashMap
    ·REDISRedisK/V存储。
   ·CONSULConsulK/V存储。
  ·JPASpring Data JPA,基于数据库。
  ·BUKET4J:一个使用Java编写的基于令牌桶算法 的限流库,其有四种模式,JCacheHazelcastApache Ignite Inifinispan,其中后面三种支持异步。
在选择粒度策略与存储方式时,应该结合自己的应 用客观选取,比如Zuul如果需要多节点部署,那粒度临 时变量存储方式就不能选择MEMEORY。选择最适合 自己应用的搭配,快速构建起自己的应用。
 
 
1.zuul-server编写说明
Spring Cloud Zuul限流
 

编写配置文件bootstrap.yml

Spring Cloud Zuul限流

 
 
 
示例采用本地内存的存储方式,在3秒的时间窗口 内不能有超过2次的接口调用。到这里,它的整合就算 完成了,我们需要做的只是修改配置文件,定制我们需 要的限流策略。eureka-serverclient-a服务不需要做任 何修改。
 

相关文章: