文档章节

服务化体系之—限流

穿林度水
 穿林度水
发布于 2016/11/07 14:27
字数 1880
阅读 6
收藏 0

服务化体系之—限流

08月 29, 2016 | Filed under 技术

(上)设计篇

在实现算法之前,先临时客串一下产品经理,尝试用最少的字,把“限流”这简单二字所展开的种种需求给说清楚。

 

1.各种目的

1. 保护每个服务节点。
2. 保护服务集群背后的资源,比如数据库。
3. 避免单个调用者过度使用服务,影响其他调用者。

 

2. 各种设定维度

2.1. 节点级别 vs 集群级别

如果以保护每个服务节点为目的,可以简单的在本地做节点级别的限流。

但如果以保护服务集群背后的资源为目的,就需要做集群级别的限流。

集群级别的一个做法是使用Redis, Memcached之类做一个集群级别的计数器。但额外多一次访问Redis的消耗,代价有点大。

而另一个做法是把集群限流总数分摊到每个节点上,但一是不够精准,二是如果使用Docker动态缩扩容,需要动态更新这个分摊数。

 

2.2 客户端 vs 服务端

当以避免单个调用者过度使用服务为目的,可以针对客户端设定限流。

此时限流可以在客户端实现,节约了网络往返,但同样有调用者的节点 or 集群之惑。

也可以在服务端实现,让所有限流逻辑集中于一处发生。

 

2.3 服务级别 vs 方法级别

可以对消耗特别大的方法专门配置,比如复杂的查询,昂贵的写操作。

然后其他方法使用统一的值,或者配一个所有方法加起来的总和。

 

3. 各种触发条件

触发条件的设定,难点在于服务的容量,受着本服务节点的能力,背后的资源的能力,下游服务的响应的多重约束。

3.1 静态配置固定值

当然,这个固定值可以被动态更新。

3.2 根据预设规则触发

规则的条件可以是服务平均时延,可以是背后数据库的CPU情况等。

比如平时不限流,当服务时延大于100ms,则触发限流500 QPS。

还可以是多级条件,比如>100ms 限流500 QPS, >200ms 限流200 QPS。

3.3 全动态自动增减调控

这个诱人的想法,永远存在于老板的心里。

 

4. 各种处理

4.1 立刻返回拒绝错误

由客户端进行降级处理。

4.2 进行短暂的等待

短暂等待,期待有容量空余,直到超时,依然是客户端降级。

4.3 触发服务降级,调用服务端的降级方法

服务端的降级方法,走服务端的简单路径与预设值,则代表了服务端这边的态度和逻辑,各有适用的场景,等下一篇《服务降级》 再详述。

 

(下)实现篇

开涛的《聊聊高并发系统之限流特技》 已讲得非常好,这里再简单补充两句。

另一篇《接口限流算法总结》 也非常好非常详细,差别只在于对令牌桶的突发量的描述上,我有我自己的理解。

1. 并发控制

并发控制本身就是一种最简单的限流,包括:

框架本身的连接/线程限制
各种数据库连接池,Http连接池
服务/方法级别的信号量计数器限制

 

2. 窗口流量控制

窗口流量控制有几种做法。

一种最简单的计数器,维护一个单位时间内的Counter,如判断单位时间已经过去,则将Counter重置零。开涛文章里利用guava cache也是一种做法。

但此做法有时被认为粒度太粗,没有把QPS平摊到一秒的各个毫秒里,同时也没有很好的处理单位时间的边界,比如在前一秒的最后一毫秒里和下一秒的第一毫秒都触发了最大的请求数,将目光移动一下,就看到在两毫秒内发生了两倍的TPS。

于是,另一个改进版的做法是把单位时间拆分,比如把1秒分成5个200毫秒宽的桶,然后以滑动窗口来计算限流,好像就能很大程度上解决上面的两个问题了。。。。滑动窗口的算法,统一到《熔断篇》再来讨论。

最后一组就是漏桶算法或令牌桶算法了,下面会详述。

另外,集群规模的计数器,基于Memcachd或Redis的实现,也见开涛的博客。

 

3. 令牌桶算法(Token Bucket )

  1. 1. 随着时间流逝,系统会按速率 1/rate 的时间间隔(如果rate=100,则间隔是10ms)往桶里加入Token
  2. 2. 如果桶满了(burst),则丢弃新加入的令牌
  3. 3. 每个请求进来,都要消耗一个Token,如果桶空了,则丢弃请求或等待有新的令牌放入。

非常形象,好像不需要更多解析

4. 漏桶算法(Leaky Bucket )

简单的想象有一个木桶,有新请求就是不断的倒水进来,然后桶底下有个洞,按照固定的速率把水漏走,如果水进来的速度比漏走的快,桶可能就会满了,然后就拒绝请求。

可见,两个算法的基本描述上,只是方向不一样,其他没什么不同的。所以WikiMedia里说, 两个算法实现可以一样,对于相同的参数得到的限流效果是一样的。

 

5. Guava版的令牌桶实现 -- RateLimiter

Guava已实现了一个性能非常好的RateLimiter,基本不需要我们再费心实现。但其中有一些实现的细节,需要我们留意:

1. 支持桶外预借的突发

突发,原本是指如果单位时间的前半段流量较少,桶里会积累一些令牌,然后支持来一波大的瞬时流量,将前面积累的令牌消耗掉。

但在RateLimiter的实现里,还多了个桶外预借(我自己给他的命名),就是即使桶里没有多少令牌,你也可以消耗一波大的,然后桶里面在时间 段内都没有新令牌。比如桶的容量是5,桶里面现在只有1个令牌,如果你要拿5个令牌,也可以,清了桶里的一个令牌,再预借4个。然后再过800毫秒,桶里 才会出现新令牌。

可见,Guava版的RateLimiter对突发的支持,比原版的两种算法都要大,你几乎随时都可以一次过消费burst个令牌,不管现在桶里有没有积累的令牌。

不过有个副作用,就是如果前面都没什么流量,桶里累积了5个令牌,则你其实可以一次过消费10个令牌。。。不过那么一下,超借完接下来还是固定速率的,直到还清了旧账,才可能再来那么一下。

2. 支持等待可用令牌与立刻返回两种接口

3. 单位时段是秒,这有点不太好用,不支持设定5分钟的单位。

4. 发令牌的计算粒度是MicroSeconds,也就是最多支持一百万的QPS。

有关的...

本文转载自:http://www.cnblogs.com/clds/p/5850086.html

上一篇: zookeeper 客户端
下一篇: liunx
穿林度水
粉丝 0
博文 250
码字总数 167120
作品 0
海淀
程序员
私信 提问
限流和降级(下) | 如何打造平台稳定性能力(二)

上一期我们谈到了阿里巴巴早期是通过通过在 Nginx 上实现的扩展组件TMD(taobao missile defense淘宝导弹防御系统)实现了接入层限流的主要工作,TMD系统可通过域名类限流、cookie限流、黑名...

中间件小哥
2018/08/27
0
0
控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[下篇]

通过《上篇》介绍,我们知道了如何通过编程和配置的方式设置相应的最大并发量,从而指导WCF的限流体系按照你设定的值对并发的服务调用请求进行限流控制。那么,在WCF框架体系内部,整个过程是...

长平狐
2012/09/04
351
0
控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[上篇]

WCF是一个基于多线程的消息监听、接收和处理框架体系,能够同时应付来自相同或者不同客户端的服务调用请求,并提供完善的同步机制确保状态的一致性。一方面,我们期望WCF服务端能够处理尽可能...

长平狐
2012/09/04
114
0
限流和降级(上) | 如何打造平台稳定性能力(一)

在整个稳定性体系中,所包含的范围非常广泛,从机房的布线、网络通信、硬件部署、应用架构、数据容灾等方面都与之相关。从共享服务中台的角度看,则更多的是从应用架构设计和中间件平台的维度...

中间件小哥
2018/08/16
0
0
鹰眼跟踪、限流降级,EDAS的微服务解决之道

本文主要从服务化的起源开始讲起,围绕EDAS介绍这些年来,随着阿里庞大的电商技术平台流量和并发不断攀升过程中,中间件的微服务技术面临的一系列挑战及解决方法。同时,也会向读者介绍历次双...

nileader
2016/10/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

NIO基于长度域的报文在Netty下的解码

1, 先复习一下粘包/拆包 1.1, 粘包/拆包的含义 TCP是个“流”协议, 并不了解上层业务数据的具体含义, 它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP...

老菜鸟0217
今天
8
0
从零开始搭建spring-cloud(2) ----ribbon

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。 其实我们已经在上...

Vincent-Duan
今天
17
0
get和post的区别?

doGet:路径传参。效率高,安全性差(get的传送数据量有限制,不能大于2Kb) doPOST:实体传参。效率低,安全性好 建议: 1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Pos...

花无谢
昨天
4
0
当谈论迭代器时,我谈些什么?

当谈论迭代器时,我谈些什么? 花下猫语:之前说过,我对于编程语言跟其它学科的融合非常感兴趣,但我还说漏了一点,就是我对于 Python 跟其它编程语言的对比学习,也很感兴趣。所以,我一直...

豌豆花下猫
昨天
14
0
10天学Python直接做项目,我做了这5件事

初学者如何尽快上手python? 市面上关于如何学python的资料很多,但是讲的都太复杂。 我就是很简单的几句话,从小白到开发工程师,我只做了五件事。 我觉得任何商业计划书如果不能用几句话讲...

Python派森
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部