基于分布式环境下限流系统的设计

标签: Redis 流控 | 发表时间:2017-11-18 11:00 | 作者:
出处:http://yoursite.com/


前提

业务背景

就拿前些天的双十一的 “抢券活动” 来说,一般是设置整点开始抢的,你想想,淘宝的用户群体非常大,可以达到亿级别,而服务接口每秒能处理的量是有限的,那么这个时候问题就会出现,我们如何通过程序来控制用户抢券呢,于是就必须加上这个限流功能了。

生产环境

1、服务接口所能提供的服务上限(limit)假如是 500次/s

2、用户请求接口的次数未知,QPS可能达到 800次/s,1000次/s,或者更高

3、当服务接口的访问频率超过 500次/s,超过的量将拒绝服务,多出的信息将会丢失

4、线上环境是多节点部署的,但是调用的是同一个服务接口

于是,为了保证服务的可用性,就要对服务接口调用的速率进行限制(接口限流)。

什么是限流?

限流是对系统的 出入流量进行 控制,防止大流量出入,导致 资源不足,系统不稳定。

限流系统是对资源访问的控制组件,控制主要的两个功能: 限流策略熔断策略,对于熔断策略,不同的系统有不同的熔断策略诉求,有的系统希望直接拒绝、有的系统希望排队等待、有的系统希望服务降级、有的系统会定制自己的熔断策略,这里只针对 限流策略这个功能做详细的设计。

限流算法

1、限制瞬时并发数

Guava RateLimiter 提供了令牌桶算法实现:平滑突发限流(SmoothBursty)和平滑预热限流(SmoothWarmingUp)实现。

2、限制某个接口的时间窗最大请求数

即一个时间窗口内的请求数,如想限制某个接口/服务每秒/每分钟/每天的请求数/调用量。如一些基础服务会被很多其他系统调用,比如商品详情页服务会调用基础商品服务调用,但是怕因为更新量比较大将基础服务打挂,这时我们要对每秒/每分钟的调用量进行限速;一种实现方式如下所示:

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     
LoadingCache<Long, AtomicLong> counter =
CacheBuilder.newBuilder()
.expireAfterWrite(2, TimeUnit.SECONDS)
.build(new CacheLoader<Long, AtomicLong>() {
@Override
public AtomicLong load(Long seconds) throws Exception {
return new AtomicLong(0);
}
});
long limit = 1000;
while(true) {
//得到当前秒
long currentSeconds = System.currentTimeMillis() / 1000;
if(counter.get(currentSeconds).incrementAndGet() > limit) {
System.out.println("限流了:" + currentSeconds);
continue;
}
//业务处理
}

使用Guava的Cache来存储计数器,过期时间设置为2秒(保证1秒内的计数器是有的),然后我们获取当前时间戳然后取秒数来作为KEY进行计数统计和限流,这种方式也是简单粗暴,刚才说的场景够用了。

3、令牌桶

算法描述:

  • 假如用户配置的平均发送速率为r,则每隔1/r秒一个令牌被加入到桶中
  • 假设桶中最多可以存放b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃
  • 当流量以速率v进入,从桶中以速率v取令牌,拿到令牌的流量通过,拿不到令牌流量不通过,执行熔断逻辑

属性

  • 长期来看,符合流量的速率是受到令牌添加速率的影响,被稳定为:r
  • 因为令牌桶有一定的存储量,可以抵挡一定的流量突发情况
    • M是以字节/秒为单位的最大可能传输速率。 M>r
    • T max = b/(M-r) 承受最大传输速率的时间
    • B max = T max * M 承受最大传输速率的时间内传输的流量

优点:流量比较平滑,并且可以抵挡一定的流量突发情况

4、Google guava 提供的工具库中 RateLimiter 类(内部也是采用令牌桶算法实现)

最快的方式是使用 RateLimit 类,但是这仅限制在单节点,如果是分布式系统,每个节点的 QPS 是一样的,请求量到服务接口那的话就是 QPS * 节点数 了。所以这种方案在分布式的情况下不适用!

5、基于 Redis 实现,存储两个 key,一个用于计时,一个用于计数。请求每调用一次,计数器增加 1,若在计时器时间内计数器未超过阈值,则可以处理任务。

这种能够很好地解决了分布式环境下多实例所导致的并发问题。因为使用redis设置的计时器和计数器均是全局唯一的,不管多少个节点,它们使用的都是同样的计时器和计数器,因此可以做到非常精准的流控。

代码就不公布了,毕竟涉及公司隐私了。

最后

参考文章:

基于Redis的限流系统的设计

感兴趣的可以看看别人的代码是怎么写的: https://github.com/wukq/rate-limiter

转载请注明文章地址为: http://www.54tianzhisheng.cn/2017/11/18/flow-control/

相关 [分布 环境 系统] 推荐:

基于分布式环境下限流系统的设计

- - Zhisheng的博客
就拿前些天的双十一的 “抢券活动” 来说,一般是设置整点开始抢的,你想想,淘宝的用户群体非常大,可以达到亿级别,而服务接口每秒能处理的量是有限的,那么这个时候问题就会出现,我们如何通过程序来控制用户抢券呢,于是就必须加上这个限流功能了. 1、服务接口所能提供的服务上限(limit)假如是 500次/s.

jmeter分布式环境搭建

- - 行业应用 - ITeye博客
1       准备机器. N作为从机,1台作为控制器. 注:从机作为虚拟用户发起机器. 1 关闭所有从机防火墙   ---从机. 2 所有的客户端应该都是在同一个子网中. 3 确保jMeter可以访问这个服务器 ---Ping   --客户端能访问服务器. 4 确保各个客户端的jMeter的版本都是一致的,不同版本的Jmeter可能不会协同工作.

分布式集群环境hadoop、hbase、zookeeper搭建(全)

- - CSDN博客云计算推荐文章
集群环境至少需要3个节点(也就是3台服务器设备):1个Master,2个Slave,节点之间局域网连接,可以相互ping通,下面举例说明,配置节点IP分配如下:. 三个节点均使用centos 6.3系统,为了便于维护,集群环境配置项最好使用相同用户名、用户密码、相同hadoop、hbase、zookeeper目录结构.

ZooKeeper-- 管理分布式环境中的数据

- - 互联网 - ITeye博客
1.随着分布式应用的不断深入,需要对集群管理逐步透明化. 监控集群和作业状态;可以充分的利用ZK的独有特性,熟悉程度决定应用高度. 2.Service端具有fast fail特性,非常健壮,无单点,不超过半数Server挂掉不会影响提供服务. 3.zookeeper名字空间由节点znode构成,其组织方式类似于文件系统, 其各个节点相当于目录和文件,通 过路径作为唯一标示.

苹果MAC操作系统上搭建Android开发平台环境

- - CSDN博客移动开发推荐文章
在MAC中安装并搭建Android开发环境的详细步骤和教程. Android的开发平台搭建主要需要的工具有:Java虚拟机JDK、Eclipse、Eclipse插件ADT(Android Developer Tool)和Android开发包SDK,以下是具体的安装方法. 在MAC中已经为我们预装了JDK并默认配置了Java系统变量,因此JDK对我们来说直接使用即可,查看MAC中的JDK版本方法是在命令行(硬盘/应用程序/实用工具/终端)中输入"java -version"并回车即可.

2017年第一季度安卓系统安全性生态环境研究

- - FreeBuf.COM | 关注黑客与极客
此报告数据来源为70万份“360透视镜”(360手机卫士团队发布的一款专业检测手机安全漏洞的APP)用户主动上传的漏洞检测报告,检测内容包括最近两年的Android和Chrome安全公告中检出率最高的42个漏洞,涵盖了Android系统的各个层面. 检测结果显示,截止至2017年4月,70万用户中99.99%的Android手机存在安全漏洞,仅有4台手机完全修复了检测中所包含的42个漏洞.

分布式缓存系统 Xixibase

- Le - 开源中国社区最新软件
Xixibase是一个高性能,跨平台的分布式缓存系统. Xixibase server 采用 C++ 实现,底层网络库采用的是Boost Asio. Xixibase 主要特点: 1. 实现'Local Cache'功能, 当客户端打开'Local Cache'选项, 客户端可以将数据同时存储在Server 端和本地,并且保证本地数据和Server 端的数据的一致性.

分布式检索系统 ElasticSearch

- - 丕子
ElasticSearch最近发展不错,github等都用它,可以关注I下. ElasticSearch是分布式,REST风格,搜索和分析系统. 具有实时数据,实时分析,分布式,高可用性,多租户,全文搜索,面向文档,冲突管理,自由模式,rest风格API,每个操作的持久性,Apache 2的开源许可证,基于Apache Lucene之上的特点.

分布式消息系统:Kafka

- - 标点符
Kafka是分布式发布-订阅消息系统. 它最初由LinkedIn公司开发,之后成为Apache项目的一部分. Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务. 在大数据系统中,常常会碰到一个问题,整个大数据是由各个子系统组成,数据需要在各个子系统中高性能,低延迟的不停流转. 传统的企业消息系统并不是非常适合大规模的数据处理.

分布式系统介绍-PNUTS

- - CSDN博客推荐文章
PNUTS是Yahoo!的分布式数据库系统,支持地域上分布的大规模并发操作. 它根据主键的范围区间或者其哈希值的范围区间将表拆分为表单元(Tablet),多个表单元存储在一个服务器上. 一个表单元控制器根据服务器的负载情况,进行表单元的迁移和拆分. 每条记录的数据都没有固定的模式(采用JSON格式的文本).